dslinux/user/pixil/sys/par/tools Makefile parget.c parset.c partags.h parxml.c xmlexport.c xmlimport.c

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:27:11 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/sys/par/tools
In directory antilope:/tmp/cvs-serv11916/sys/par/tools

Added Files:
	Makefile parget.c parset.c partags.h parxml.c xmlexport.c 
	xmlimport.c 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: xmlimport.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>

#include <par/pardb.h>
#include <xml/xml.h>

#define DO_APPEND     0x1
#define DO_INPUT_FILE 0x2
#define DO_VERBOSE    0x4

extern int parseXML(char *file, tree_t * head);


void
print_usage(void)
{
    printf("\n-------\n");
    printf("xmlimport [-h] [-a] -i <xml file> <DB file>\n\n");

    printf
	("[-a, --append] - If the database file exists, then append the new data to it\n");
    printf("[-h, --help] - print this screen\n");
    printf("[-i, --input] - The input XML file\n");
    printf("[-v, --verbose] - Print a ton of messages\n");
    printf("-------\n\n");
}

int
main(int argc, char **argv)
{

    unsigned short flags = 0;

    char input_filename[512];
    char output_filename[512];

    db_handle *db = 0;
    tree_t *tree = 0;

    while (1) {
	signed char c;
	int option_index;

	static struct option long_options[] = {
	    {"append", 0, 0, 'a'},
	    {"help", 0, 0, 'h'},
	    {"input", 1, 0, 'i'},
	    {"verbose", 0, 0, 'v'},
	    {0, 0, 0, 0}
	};

	c = getopt_long(argc, argv, "ahi:v", long_options, &option_index);
	if (c == -1)
	    break;

	switch (c) {
	case 'a':
	    flags |= DO_APPEND;
	    break;

	case 'h':
	    print_usage();
	    exit(0);

	case 'i':
	    strcpy(input_filename, optarg);
	    flags |= DO_INPUT_FILE;
	    break;

	case 'v':
	    flags |= DO_VERBOSE;
	    break;

	default:
	    print_usage();
	    exit(-1);
	}
    }

    /* Grab the output file */

    if (optind < argc)
	strcpy(output_filename, argv[optind]);
    else {
	fprintf(stderr, "ERROR: You must specify an output database file\n");
	print_usage();
	exit(-1);
    }

    /* FIXME:  Allow stdin!!!! */

    if (!(flags & DO_INPUT_FILE)) {
	fprintf(stderr, "ERROR: You must specify an input XML file\n");
	print_usage();
	exit(-1);
    }

    if (!db_newTree(&tree)) {
	fprintf(stderr,
		"ERROR: Got internal error %d while creating the tree\n",
		pardb_errno);
	exit(-1);
    }

    if (!access(output_filename, R_OK)) {
	if (flags & DO_APPEND) {
	    int ret;

	    if (flags & DO_VERBOSE)
		printf("Reading database file %s into memory...\n",
		       output_filename);

	    db = db_openDB(output_filename, PAR_DB_MODE_RDONLY);

	    if (!db) {
		switch (pardb_errno) {
		case PARDB_FILEERR:
		    fprintf(stderr, "ERROR: File error while opening %s.\n",
			    output_filename);
		    break;

		case PARDB_BADDB:
		    fprintf(stderr, "ERROR: %s is not a PAR database!\n",
			    output_filename);
		    break;

		default:
		    fprintf(stderr,
			    "ERROR: Got internal error %d while opening %s.\n",
			    pardb_errno, output_filename);
		    break;
		}

		goto exitError;
	    }

	    ret = db_loadTree(db, tree);
	    db_closeDB(db);
	    db = 0;

	    if (ret == -1) {
		fprintf(stderr,
			"ERROR:  Got internal error %d while reading %s.\n",
			pardb_errno, output_filename);
		goto exitError;
	    }
	} else {
	    fprintf(stderr,
		    "ERROR:  %s already exists. Use --append to add data to an existing file.\n",
		    output_filename);
	    goto exitError;
	}
    }

    /* Now parse the XML into the tree */
    if (flags & DO_VERBOSE)
	printf("Parsing the XML file %s....\n", input_filename);

    if (parseXML(input_filename, tree) != 0) {
	fprintf(stderr, "ERROR:  Got an error while parsing the XML file\n");
	goto exitError;
    }

    if (flags & DO_VERBOSE)
	printf("Opening the database %s for writing...\n", output_filename);

    /* Open the database to write out */
    db = db_newDB(output_filename, PAR_DB_NORMAL);

    if (!db) {
	if (pardb_errno == PARDB_FILEERR)
	    fprintf(stderr, "ERROR:  File error while creating %s.\n",
		    output_filename);
	else
	    fprintf(stderr,
		    "ERROR:  Got internal error %d while creating %s.\n",
		    pardb_errno, output_filename);

	goto exitError;
    }

    /* Now save the entire tree */

    if (flags & DO_VERBOSE)
	printf("Writing the database...\n");

    if (db_saveTree(db, tree)) {
	fprintf(stderr, "ERROR:  Got internal error %d while saving %s.\n",
		pardb_errno, output_filename);
	goto exitError;
    }

    if (flags & DO_VERBOSE)
	printf("The file was succesfully imported.\n");

    /* Sucess all around.  Close the database and leave */
    db_closeDB(db);
    return (0);

  exitError:

    if (tree)
	db_freeTree(tree);
    if (db)
	db_closeDB(db);

    return (-1);
}

--- NEW FILE: parset.c ---
 /* (c) 2003 Century Software, Inc.   All Rights Reserved.     
    *                                                                       
    * This file is part of the PIXIL Operating Environment                 
    *                                                                       
    * The use, copying and distribution of this file is governed by one    
    * of two licenses, the PIXIL Commercial License, or the GNU General    
    * Public License, version 2.                                           
    *                                                                       
    * Licensees holding a valid PIXIL Commercial License may use this file 
    * in accordance with the PIXIL Commercial License Agreement provided   
    * with the Software. Others are governed under the terms of the GNU   
    * General Public License version 2.                                    
    *                                                                       
    * This file may be distributed and/or modified under the terms of the  
    * GNU General Public License version 2 as published by the Free        
    * Software Foundation and appearing in the file LICENSE.GPL included   
    * in the packaging of this file.                                      
    *                                                                       
    * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
    * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
    * PARTICULAR PURPOSE.                                                  
    *                                                                       
    * RESTRICTED RIGHTS LEGEND                                             
    *                                                                     
    * Use, duplication, or disclosure by the government is subject to      
    * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
    * Technical Data and Computer Software clause in DAR 7-104.9(a).       
    *                                                                      
    * See http://www.pixil.org/gpl/ for GPL licensing       
    * information.                                                         
    *                                                                      
    * See http://www.pixil.org/license.html or              
    * email cetsales at centurysoftware.com for information about the PIXIL   
    * Commercial License Agreement, or if any conditions of this licensing 
    * are not clear to you.                                                
  */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <ctype.h>

#include <par/pardb.h>

void
print_usage(void)
{
    printf("\n-------\n");
    printf("parset [-h] -d <DB file> -t <type> <node> <value>\n\n");

    printf("[-h, --help] - print this screen.\n");
    printf("[-d, --db] - The database to read from.\n");
    printf("             (Uses the value of environment variable\n");
    printf("              $PARFILE if not specified).\n");
    printf("[-t, --type] - The type of variable being written.\n");
    printf("               (assumes TEXT if not specified).\n");
    printf("-------\n\n");
}

#define HAVE_DB_FILE 0x1

int
main(int argc, char **argv)
{

    db_handle *db;

    int ret = 0;

    unsigned short type = PAR_TEXT;
    unsigned char flags = 0;

    char *database_filename = 0;
    char *value = 0, *node;

    while (1) {
	signed char c;
	int option_index;
	char letter;

	static struct option long_options[] = {
	    {"help", 0, 0, 'h'},
	    {"db", 1, 0, 'd'},
	    {"type", 1, 0, 't'},
	    {0, 0, 0, 0}
	};

	c = getopt_long(argc, argv, "d:t:h", long_options, &option_index);
	if (c == -1)
	    break;

	switch (c) {
	case 'h':
	    print_usage();
	    return (0);

	case 't':
	    letter = tolower(optarg[0]);

	    switch (letter) {
	    case 't':
		type = PAR_TEXT;
		break;

	    case 'f':
		type = PAR_FLOAT;
		break;

	    case 'i':
		type = PAR_INT;
		break;

	    case 'b':
		type = PAR_BOOL;
		break;
	    }

	    break;

	case 'd':
	    database_filename = alloca(strlen(optarg) + 1);
	    strcpy(database_filename, optarg);

	    flags |= HAVE_DB_FILE;
	    break;

	default:
	    print_usage();
	    return (-1);
	}
    }

    if (optind < argc)
	node = argv[optind++];
    else {
	fprintf(stderr, "ERROR: You must specific a node to search for\n");
	print_usage();
	return (-1);
    }

    if (optind < argc)
	value = argv[optind++];
    else {
	fprintf(stderr, "ERROR:  You must specify a value to set\n");
	print_usage();
	return (-1);
    }

    if (!(flags & HAVE_DB_FILE)) {
	database_filename = db_getDefaultDB();
	if (!database_filename) {
	    fprintf(stderr,
		    "ERROR:  Could not determine the default database.\n");
	    print_usage();
	    return (-1);
	}
    }

    /* Open the file, search for the node, and output it to stdout */
    db = db_openDB(database_filename, PAR_DB_MODE_RW);
    if (!db) {
	switch (pardb_errno) {
	case PARDB_NOFILE:
	    fprintf(stderr, "ERROR:  File %s does not exist.\n",
		    database_filename);
	    break;

	case PARDB_FILEERR:
	    fprintf(stderr, "ERROR:  Error while opening %s.\n",
		    database_filename);
	    break;

	case PARDB_BADDB:
	    fprintf(stderr, "ERROR:  %s is not a PAR database\n",
		    database_filename);
	    break;

	default:
	    fprintf(stderr,
		    "ERROR:  Internal error %d occured while opening %s\n",
		    pardb_errno, database_filename);
	    break;
	}

	return (-1);
    }

    switch (type) {

    case PAR_TEXT:
	ret = db_addNode(db, node, value, strlen(value), PAR_TEXT);
	break;

    case PAR_INT:{
	    int ival;

	    if (strlen(value) > 2 && (strncmp(value, "0x", 2) == 0))
		ival = strtol(value, 0, 16);
	    else
		ival = atoi(value);

	    ret = db_addNode(db, node, value, ival, PAR_INT);
	}

	break;

    case PAR_FLOAT:{
	    double fval = atof(value);
	    ret = db_addNode(db, node, value, fval, PAR_FLOAT);
	}

	break;

    case PAR_BOOL:{

	    unsigned char bool = 0;

	    if (*value >= '0' && *value <= '9') {
		int val = atoi(value);
		bool = ((val == 0) ? 0 : 1);
	    } else {
		int i;
		struct bool_list
		{
		    char word[5];
		    char value;
		}
		bools[] =
		{ {
		"yes", 1}
		, {
		"no", 0}
		, {
		"true", 1}
		, {
		"false", 0}
		, {
		"on", 1}
		, {
		"off", 0}
		};

		for (i = 0; i < strlen(value); i++)
		    tolower(value[i]);

		for (i = 0; i < 6; i++) {
		    if (strlen(value) < strlen(bools[i].word))
			continue;

		    if (strncmp(bools[i].word, value, strlen(bools[i].word))
			== 0)
			bool = bools[i].value;
		    break;
		}

		if (i == 6)
		    bool = 0;
	    }

	    ret = db_addNode(db, node, value, bool, PAR_BOOL);
	}
	break;
    }

    db_closeDB(db);

    if (ret == -1) {
	fprintf(stderr,
		"ERROR:  Internal error %d occured while setting %s\n",
		pardb_errno, node);
	return (-1);
    }

    return (0);
}

--- NEW FILE: partags.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


static xml_tag tagPref[] = {
    {"pref", 0, init_key, data_key, 0},
    {"", 0, 0}
};

static xml_tag tagCategory[] = {
    {"category", tagPref, init_section, 0, 0},
    {"", 0, 0}
};

static xml_tag tagPreferences[] = {
    {"preferences", tagCategory, generic_init, 0, 0},
    {"", 0, 0}
};

static xml_tag tagAppSettings[] = {
    {"preferences", tagCategory, generic_init, 0, 0},
    {"title", 0, 0, data_text, 0},
    {"exec", 0, 0, data_text, 0},
    {"workdir", 0, 0, data_text, 0},
    {"icon", 0, 0, data_text, 0},
    {"defargs", 0, 0, data_text, 0},
    {"", 0, 0}
};

static xml_tag tagApp[] = {
    {"app", tagAppSettings, init_section, 0, 0},
    {"", 0, 0}
};

static xml_tag tagCap[] = {
    {"cap", 0, 0, data_caplist, 0},
    {"", 0, 0}
};

static xml_tag tagDirectories[] = {
    {"icondir", 0, 0, data_text, 0},
    {"bindir", 0, 0, data_text, 0},
    {"themedir", 0, 0, data_text, 0},
    {"fontdir", 0, 0, data_text, 0 },
    {"", 0, 0}
};

static xml_tag tagScrtopCat[] = {
    {"title", 0, 0, data_text, 0},
    {"applist", 0, 0, generic_textlist, 0},
    {"", 0, 0}
};

static xml_tag tagCategories[] = {
    {"category", tagScrtopCat, init_section, 0, 0},
    {"", 0, 0}
};

/* The bgstyle is unique because it is a list of keywords */

static xml_tag colorSettings[] = {
    {"color", 0, 0, data_color, 0},
    {"", 0, 0}
};

static xml_tag appletSettings[] = {
  { "applet", 0, applet_init, applet_data, 0 },
  {"", 0, 0}
};

static xml_tag tagSettings[] = {
    {"bgimage", 0, 0, data_text, 0},
    {"bgstyle", 0, 0, data_text, 0},
    {"appwidth", 0, 0, data_value, 0},
    {"appheight", 0, 0, data_value, 0},
    {"colors", colorSettings, generic_init, 0, 0},
    {"applets", appletSettings, generic_init, 0, 0 },
    {"", 0, 0}
};

static xml_tag tagInputOptions[] = {
    {"title", 0, 0, data_text, 0},
    {"app", 0, 0, data_text, 0},
    {"icon", 0, 0, data_text, 0},
    {"", 0, 0}
};

static xml_tag tagInputs[] = {
    {"input", tagInputOptions, init_section, 0, 0},
    {"", 0, 0}
};

/* These are the tags for the screentop */

static xml_tag tagScreentop[] = {
    {"directories", tagDirectories, generic_init, 0, 0},
    {"categories", tagCategories, generic_init, 0, 0},
    {"inputs", tagInputs, generic_init, 0, 0},
    {"settings", tagSettings, generic_init, 0, 0},
    {"", 0, 0}
};

/* These are the toplevel tags */

static xml_tag tagToplevel[] = {
    {"global", tagPreferences, generic_init, 0, 0},
    {"application", tagApp, generic_init, 0, 0},
    {"capabilities", tagCap, generic_init, 0, 0},
    {"screentop", tagScreentop, generic_init, 0, 0},
    {"", 0, 0}
};



/* Global PAR settings used for encoding */

xml_encode encodePref[] = {
    {"pref", "*", 0, prefs_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeCategory[] = {
    {"category", "*", encodePref, category_header, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodePreferences[] = {
    {"preferences", "preferences", encodeCategory, 0, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeAppSettings[] = {
    {"title", "title", 0, par_data_header, par_data_footer, par_data},
    {"exec", "exec", 0, par_data_header, par_data_footer, par_data},
    {"workdir", "workdir", 0, par_data_header, par_data_footer, par_data},
    {"icon", "icon", 0, par_data_header, par_data_footer, par_data},
    {"defargs", "defargs", 0, par_data_header, par_data_footer, par_data},
    {"wmcategory", "wmcategory", 0, par_data_header, par_data_footer,
     par_data},
    {"preferences", "preferences", encodeCategory, 0, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeApp[] = {
    {"app", "*", encodeAppSettings, app_header, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeCap[] = {
    {"cap", "*", 0, par_named_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeDirectories[] = {
    {"icondir", "icondir", 0, par_data_header, par_data_footer, par_data},
    {"bindir", "bindir", 0, par_data_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeScrtopCats[] = {
    {"title", "title", 0, par_data_header, par_data_footer, par_data},
    {"applist", "applist", 0, par_data_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeColors[] = {
    {"color", "*", 0, par_named_header, par_data_footer, par_color},
    {"", "", 0, 0, 0}
};

xml_encode encodeSettings[] = {
    {"bgimage", "bgimage", 0, par_data_header, par_data_footer, par_data},
    {"bgstyle", "bgstyle", 0, par_data_header, par_data_footer, par_data},
    {"appwidth", "appwidth", 0, par_data_header, par_data_footer, par_data},
    {"appheight", "appheight", 0, par_data_header, par_data_footer, par_data},

    {"colors", "colors", encodeColors, 0, 0, 0},
    {"theme", "theme", 0, par_data_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeScrtopInput[] = {
    {"title", "title", 0, par_data_header, par_data_footer, par_data},
    {"app", "app", 0, par_data_header, par_data_footer, par_data},
    {"icon", "icon", 0, par_data_header, par_data_footer, par_data},
    {"", "", 0, 0, 0}
};

xml_encode encodeCategories[] = {
    {"category", "*", encodeScrtopCats, category_header, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeInputs[] = {
    {"input", "*", encodeScrtopInput, category_header, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeScrtop[] = {
    {"directories", "directories", encodeDirectories, 0, 0, 0},
    {"categories", "categories", encodeCategories, 0, 0, 0},
    {"inputs", "inputs", encodeInputs, 0, 0, 0},
    {"settings", "settings", encodeSettings, 0, 0, 0},
    {"", "", 0, 0, 0}
};

xml_encode encodeGlobal[] = {
    {"global", "global", encodePreferences, 0, 0, 0},
    {"application", "application", encodeApp, 0, 0, 0},
    {"capabilities", "capabilities", encodeCap, 0, 0, 0},
    {"screentop", "screentop", encodeScrtop, 0, 0, 0},
    {"", "", 0, 0, 0}
};

--- NEW FILE: parxml.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include <par/pardb.h>
#include "database.h"
#include <xml/xml.h>

static void *generic_init(xml_token *, void *);

/* These are the local decoding functions */

static void *init_key(xml_token *, void *);
static void *data_key(xml_token *, void *, char *, int);
static void *init_section(xml_token *, void *);

static void *data_caplist(xml_token *, void *, char *, int);
static void *generic_textlist(xml_token *, void *, char *, int);

static void *data_color(xml_token *, void *, char *, int);
static void *data_text(xml_token *, void *, char *, int);
static void *data_value(xml_token *, void *, char *, int);

static void * applet_init(xml_token *tag, void *in);
static void *applet_data(xml_token *tag, void *data, char *text, int size);

/* These are the local encoding functions */

static void prefs_header(FILE *, xml_encode *, void *, int);
static void app_header(FILE *, xml_encode *, void *, int);

static void par_named_header(FILE * stream, xml_encode * encode,
			     void *data, int indent);

static void par_data_header(FILE *, xml_encode *, void *, int);
static void par_data_footer(FILE *, xml_encode *, void *, int);
static void par_data(FILE *, void *);
static void par_color(FILE *, void *);

static void category_header(FILE *, xml_encode *, void *, int);


/* The tags are defined here for readabilty */
#include "partags.h"

static void *
init_key(xml_token * tag, void *in)
{

    void *out = 0;
    xml_prop *prop;

    if (!in) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    for (prop = tag->props; prop; prop = prop->next) {
	if (strcmp(prop->keyword, "key") == 0) {
	    out = (void *) tree_addNode((tree_t *) in, prop->value);
	    break;
	}
    }

    return (out);
}

/* This is a generic function that will take a item and append it to an */
/* ever growing list */

static void *
generic_textlist(xml_token * tag, void *data, char *text, int size)
{

    tree_t *node;
    if (!data) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    /* First, we need to see if this node already exists in the tree */
    node = tree_findChildNode((tree_t *) data, tag->tag);

    if (node) {
	char *ndata = alloca(node->size + strlen(text) + 2);
	sprintf(ndata, "%s %s", (char *) node->data, text);

	tree_addData(node, ndata, strlen(ndata), PAR_TEXT);
    } else {
	node = tree_addNode((tree_t *) data, tag->tag);
	tree_addData(node, text, size, PAR_TEXT);
    }

    return ((void *) node);
}

static void *
data_caplist(xml_token * tag, void *data, char *text, int size)
{

    char *lname = 0;
    tree_t *node;
    xml_prop *prop;

    if (!data) {
	fprintf(stderr, "No data for tag %s\n", tag->tag);
	return (0);
    }

    for (prop = tag->props; prop; prop = prop->next) {
	if (strcmp(prop->keyword, "name") == 0) {
	    lname = prop->value;
	    break;
	}
    }

    if (!lname) {
	fprintf(stderr, "Couldn't find the keyword 'name' in %s\n", tag->tag);
	return (0);
    }

    printf("Adding / Modifying %s\n", lname);

    /* First, we need to see if this node already exists in the tree */
    node = tree_findChildNode((tree_t *) data, lname);

    if (node) {
	char *ndata = alloca(node->size + strlen(text) + 2);
	sprintf(ndata, "%s %s", (char *) node->data, text);

	tree_addData(node, ndata, strlen(ndata), PAR_TEXT);
    } else {
	node = tree_addNode((tree_t *) data, lname);
	tree_addData(node, text, size, PAR_TEXT);
    }

    return ((void *) node);
}


/* Generic function to add an integer to the par database */

static void *
data_value(xml_token * tag, void *data, char *text, int size)
{

    int val;
    tree_t *node;

    if (!data) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    if (!text)
	return (0);

    /* If the first char is not a digit, then error */
    if (!isdigit(*text))
	return (0);

    val = atoi(text);
    node = tree_addNode((tree_t *) data, tag->tag);

    tree_addData(node, (void *) &val, sizeof(int), PAR_INT);

    return ((void *) node);
}

/* This is a generic function that will add a text item to the database */

static void *
data_text(xml_token * tag, void *data, char *text, int size)
{

    tree_t *node;

    if (!data) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    node = tree_addNode((tree_t *) data, tag->tag);
    tree_addData(node, text, size, PAR_TEXT);

    return ((void *) node);
}

/* This is a generic function that adds a color to the database */

static void *
data_color(xml_token * tag, void *data, char *text, int size)
{

    tree_t *node = 0;
    unsigned long val;
    xml_prop *prop;

    if (!data || !text)
	return (0);

    for (prop = tag->props; prop; prop = prop->next) {
	if (strcmp(prop->keyword, "name") == 0) {
	    node = (void *) tree_addNode((tree_t *) data, prop->value);
	    break;
	}
    }

    if (!node)
	return (0);

    if (xml_parseColor(text, &val, size) == -1) {
	fprintf(stderr, "Error - Unable to parse the color\n");
	return (0);
    }

    tree_addData(node, &val, sizeof(unsigned long), PAR_INT);
    return ((void *) node);
}

/* This is a specific function that handles a preference value */

static void *
data_key(xml_token * tag, void *data, char *text, int size)
{

    struct bool_list
    {
	char word[5];
	char value;
    }
    bools[] =
    { {
    "yes", 1}
    , {
    "no", 0}
    , {
    "true", 1}
    , {
    "false", 0}
    , {
    "on", 1}
    , {
    "off", 0}
    };

    xml_prop *prop;
    char bool = 0;		/* Default to false */

    if (!data) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    for (prop = tag->props; prop; prop = prop->next)
	if (strcmp(prop->keyword, "type") == 0)
	    break;

    /* If no keyword was specified, then assume text */

    if (!prop) {
	tree_addData((tree_t *) data, text, size, PAR_TEXT);
	return (data);
    }

    /* Set the keyword to lower case */

    xml_lowerCase(prop->value, -1);

    if (strcmp(prop->value, "str") == 0) {
	tree_addData((tree_t *) data, text, size, PAR_TEXT);
	return (data);
    }

    if (strcmp(prop->value, "int") == 0) {
	int ival;

	/* Check to see if this is a hex by chance */

	if ((size > 2) && (strncmp(text, "0x", 2) == 0))
	    ival = strtol(text, 0, 16);
	else
	    ival = atoi(text);

	tree_addData((tree_t *) data, &ival, sizeof(int), PAR_INT);
	return (data);
    }

    if (strcmp(prop->value, "float") == 0) {
	double fval = atof(text);
	tree_addData((tree_t *) data, &fval, sizeof(double), PAR_FLOAT);
	return (data);
    }

    if (strcmp(prop->value, "color") == 0) {
	unsigned long val;
	if (xml_parseColor(text, &val, size) == -1) {
	    fprintf(stderr, "Error - Unable to parse the color\n");
	    return (0);
	}

	tree_addData((tree_t *) data, &val, sizeof(unsigned long), PAR_COLOR);
	return (data);
    }

    if (strcmp(prop->value, "bool")) {
	fprintf(stderr, "Error - Invalid field type %s\n", prop->value);
	return (0);
    }

    if (*text >= '0' && *text <= '9') {
	int val = atoi(text);
	bool = ((val == 0) ? 0 : 1);
    } else {
	int i;

	xml_lowerCase(text, size);

	for (i = 0; i < 6; i++) {
	    if (size < strlen(bools[i].word))
		continue;

	    if (strncmp(bools[i].word, text, strlen(bools[i].word)) == 0)
		bool = bools[i].value;
	    break;
	}
    }

    tree_addData((tree_t *) data, &bool, sizeof(unsigned char), PAR_BOOL);
    return (data);
}

/* This is a generic function that handles tags like this: */
/* <tagname name="value"> */

static void *
init_section(xml_token * tag, void *in)
{

    void *out = 0;
    xml_prop *prop;

    if (!in) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    for (prop = tag->props; prop; prop = prop->next) {
	if (strcmp(prop->keyword, "name") == 0) {
	    out = (void *) tree_addNode((tree_t *) in, prop->value);
	    break;
	}
    }

    return (out);
}

static void *
applet_data(xml_token * tag, void *data, char *text, int size) {
  tree_addData((tree_t *) data, text, size, PAR_TEXT);
  return data;
}

static void *
applet_init(xml_token *tag, void *in) {
  
  void *out = 0;
  xml_prop *prop;

  for (prop = tag->props; prop; prop = prop->next) {
    if (strcmp(prop->keyword, "name") == 0) {
      out = (void *) tree_addNode((tree_t *) in, prop->value);
      break;
    }
  }

  return out;
}
static void *
generic_init(xml_token * tag, void *in)
{

    void *out;

    /* Make a new node in the tree */
    if (!in) {
	fprintf(stderr, "Error - No data for tag <%s>\n", tag->tag);
	return (0);
    }

    out = (void *) tree_addNode((tree_t *) in, tag->tag);

    return (out);
}

/* This is the actual parsing function */

int
parseXML(char *file, tree_t * head)
{

    xml_parser engine;
    engine.tags = tagToplevel;

    /* Now, start the parser */
    return (xml_parseFile(&engine, file, ((void *) head)));
}

/* These are some generic headers and footers that we use */

static void
par_data_header(FILE * stream, xml_encode * encode, void *data, int indent)
{
    indentLine(stream, indent);
    fprintf(stream, "<%s>", encode->tag);
}

/* This is like some other headers, but without the \n at the end */

static void
par_named_header(FILE * stream, xml_encode * encode, void *data, int indent)
{

    tree_t *node = data;
    if (!node)
	return;

    indentLine(stream, indent);
    fprintf(stream, "<%s name=\"%s\">", encode->tag, node->keyword);
}

static void
par_data_footer(FILE * stream, xml_encode * encode, void *data, int indent)
{
    fprintf(stream, "</%s>\n", encode->tag);
}

static void
par_data(FILE * stream, void *in)
{

    tree_t *node = (tree_t *) in;

    if (!node)
	return;

    switch (node->type) {

    case PAR_NONE:
	break;

    case PAR_TEXT:
	fprintf(stream, "%s", (char *) node->data);
	break;

    case PAR_INT:
	fprintf(stream, "%i", *((int *) node->data));
	break;

    case PAR_BOOL:
	fprintf(stream, "%s", ((*((int *) node->data) == 0) ? "Yes" : "No"));
	break;

    case PAR_FLOAT:
	fprintf(stream, "%f", *((double *) node->data));
	break;

    case PAR_COLOR:
	fprintf(stream, "#%6.6lX",
		(*((unsigned long *) node->data)) & 0xFFFFFF);
	break;
    }
}

static void
par_color(FILE * stream, void *in)
{

    unsigned long val;
    tree_t *node = (tree_t *) in;
    if (!node)
	return;
    if (node->type != PAR_INT)
	return;

    val = *((unsigned long *) node->data);

    fprintf(stream, "#%6.6lX", val & 0xFFFFFF);
}



static void
prefs_header(FILE * stream, xml_encode * encode, void *data, int indent)
{

    tree_t *node = (tree_t *) data;
    if (!node)
	return;

    indentLine(stream, indent);

    fprintf(stream, "<%s key=\"%s\"", encode->tag, node->keyword);

    switch (node->type) {
    case PAR_NONE:
	break;

    case PAR_TEXT:
	fprintf(stream, " type=STR");
	break;

    case PAR_INT:
	fprintf(stream, " type=INT");
	break;

    case PAR_BOOL:
	fprintf(stream, " type=BOOL");
	break;

    case PAR_FLOAT:
	fprintf(stream, " type=FLOAT");
	break;

    case PAR_COLOR:
	fprintf(stream, " type=COLOR");
	break;
    }

    fprintf(stream, ">");
}



static void
app_header(FILE * stream, xml_encode * encode, void *data, int indent)
{

    tree_t *node = data;
    if (!node)
	return;

    indentLine(stream, indent);
    fprintf(stream, "<%s name=\"%s\">\n", encode->tag, node->keyword);
}

static void
category_header(FILE * stream, xml_encode * encode, void *data, int indent)
{

    tree_t *node = data;
    if (!node)
	return;

    indentLine(stream, indent);
    fprintf(stream, "<%s name=\"%s\">\n", encode->tag, node->keyword);
}


static void
par_xml_header(FILE * stream)
{

    char buffer[26];

    time_t curtime;

    time(&curtime);
    strcpy(buffer, ctime(&curtime));
    buffer[strlen(buffer) - 1] = 0;

    fprintf(stream, "<!-- Pixil Application Registry Database -->\n");
    fprintf(stream, "<!-- Written %s -->\n\n", buffer);
}

static void *
par_xml_find(char *keyword, void *in)
{

    tree_t *node = (tree_t *) in;

    if (!node)
	return (0);
    node = node->child;

    /* If it is a wildcard, then get the first child */
    if (keyword[0] == '*')
	return (node);

    /* Otherwise, search for the specific keyword */

    while (node) {
	if (strcmp(keyword, node->keyword) == 0)
	    return ((void *) node);

	node = node->peer;
    }

    return (0);
}

static void *
par_xml_next(char *keyword, void *in)
{

    tree_t *node = (tree_t *) in;
    if (!node)
	return (0);

    node = node->peer;

    if (keyword[0] == '*')
	return (node);

    while (node) {
	if (strcmp(keyword, node->keyword) == 0)
	    return ((void *) node);

	node = node->peer;
    }

    return (0);
}

int
encodeXML(char *filename, tree_t * head)
{

    xml_encoder engine;

    engine.header = par_xml_header;
    engine.footer = 0;
    engine.find = par_xml_find;
    engine.next = par_xml_next;

    return (xml_encodeFile(&engine, encodeGlobal, filename, (void *) head));
}

--- NEW FILE: xmlexport.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

#include <par/pardb.h>
#include <xml/xml.h>

extern int encodeXML(char *filename, tree_t * head);

void
print_usage(void)
{
    printf("\n-------\n");
    printf("xmlexport [-h] -f <XML file> <DB file>\n\n");

    printf("[-h, --help] - print this screen\n");
    printf("[-f, --file] - The XML output file to send to (if not stdout)\n");
    printf("[-v, --verbose] - Print a ton of messages\n");
    printf("-------\n\n");
}

#define DO_VERBOSE   0x01
#define HAVE_OUTPUT  0x02

int
main(int argc, char **argv)
{

    int flags = 0, ret;

    db_handle *db;

    char input_filename[512];
    char output_filename[512];

    tree_t *tree;

    while (1) {
	signed char c;
	int option_index;

	static struct option long_options[] = {
	    {"help", 0, 0, 'h'},
	    {"file", 1, 0, 'f'},
	    {"verbose", 0, 0, 'v'},
	    {0, 0, 0, 0}
	};

	c = getopt_long(argc, argv, "hd:v", long_options, &option_index);
	if (c == -1)
	    break;

	switch (c) {
	case 'h':
	    print_usage();
	    exit(0);

	case 'f':
	    strcpy(output_filename, optarg);
	    flags |= HAVE_OUTPUT;
	    break;

	case 'v':
	    flags |= DO_VERBOSE;
	    break;

	default:
	    print_usage();
	    exit(-1);
	}
    }

    if (optind < argc)
	strcpy(input_filename, argv[optind]);
    else {
	fprintf(stderr, "ERROR:  You must specify an input database\n");
	exit(-1);
    }


    /* Create a brand new tree for this to attach to */

    if (!db_newTree(&tree)) {
	fprintf(stderr, "ERROR:  Got internal error %d\n", pardb_errno);
	exit(-1);
    }

    db = db_openDB(input_filename, PAR_DB_MODE_RDONLY);

    if (!db) {
	switch (pardb_errno) {
	case PARDB_NOFILE:
	    fprintf(stderr, "ERROR:  Database file %s doesn't exist\n",
		    input_filename);
	    break;

	case PARDB_FILEERR:
	    fprintf(stderr, "ERROR:  File error wihle opening %s\n",
		    input_filename);
	    break;

	case PARDB_BADDB:
	    fprintf(stderr, "ERROR:  %s is not a PAR database\n",
		    input_filename);
	    break;

	default:
	    fprintf(stderr,
		    "ERROR:  Got internal error %d while opening %s.\n",
		    pardb_errno, input_filename);
	    break;
	}

	goto exitError;
    }

    if (db_loadTree(db, tree)) {
	fprintf(stderr, "ERROR:  Got inernal error %d while reading %s.\n",
		pardb_errno, input_filename);
	goto exitError;
    }

    db_closeDB(db);
    db = 0;

    if (!(flags & HAVE_OUTPUT))
	ret = encodeXML(0, tree);
    else
	ret = encodeXML(output_filename, tree);

    if (ret == -1) {
	fprintf(stderr,
		"ERROR: Couldn't export the database to XML format\n");
	goto exitError;
    }

    db_freeTree(tree);
    return (0);

  exitError:
    if (tree)
	db_freeTree(tree);
    if (db)
	db_closeDB(db);

    return (-1);
}

--- NEW FILE: Makefile ---
#par/tools/Makefile

# These targets are all defined in this Makefile rather than in 
# Rules.make

TARGET_EXTRAS  = platform-objs/xmlimport platform-objs/xmlexport 
TARGET_EXTRAS += platform-objs/parget platform-objs/parset

TARGET_EXTRAS += native-objs/xmlimport native-objs/xmlexport 
TARGET_EXTRAS += native-objs/parget native-objs/parset

# This is called before the build to make sure that all of 
# our directories are in place

PREBUILD_EXTRAS = $(CURDIR)/native-objs $(CURDIR)/platform-objs

# This is called after the build to install the native tools
POSTBUILD_EXTRAS = par-native-install

# This specifies the target for installing the platform tools

INSTALL_EXTRAS = par-platform-install

NATIVE_INSTALL_TARGETS = $(STAGE_DIR)/bin/native/xmlexport $(STAGE_DIR)/bin/native/xmlimport
NATIVE_INSTALL_TARGETS += $(STAGE_DIR)/bin/native/parget $(STAGE_DIR)/bin/native/parset

# The directory to install the platform tools in
INSTALL_BINDIR=$(INSTALL_DIR)/sbin

LIBS= -L$(STAGE_DIR)/lib -lxml -lpar
NATIVE_LIBS = -L$(STAGE_DIR)/lib/native/ -lxml -lpar

CLEAN_EXTRAS=par-clean

INCLUDES=-I../lib

include $(BASE_DIR)/Rules.make

par-platform-install: $(INSTALL_BINDIR)
	cp platform-objs/xmlimport platform-objs/xmlexport \
	platform-objs/parget platform-objs/parset $(INSTALL_BINDIR)

par-native-install: $(NATIVE_INSTALL_TARGETS)

par-clean:
	rm -rf platform-objs native-objs

platform-objs/xmlimport: platform-objs/xmlimport.o platform-objs/parxml.o
	$(CC) -o $@ platform-objs/xmlimport.o platform-objs/parxml.o $(LIBS)

platform-objs/xmlexport: platform-objs/xmlexport.o platform-objs/parxml.o
	$(CC) -o $@ platform-objs/xmlexport.o platform-objs/parxml.o $(LIBS)

platform-objs/parget: platform-objs/parget.o
	$(CC) -o $@ $< $(LIBS)

platform-objs/parset: platform-objs/parset.o
	$(CC) -o $@ $< $(LIBS)

## Native targets

native-objs/xmlimport: native-objs/xmlimport.o native-objs/parxml.o
	gcc -o $@ native-objs/xmlimport.o native-objs/parxml.o $(NATIVE_LIBS)

native-objs/xmlexport: native-objs/xmlexport.o native-objs/parxml.o
	gcc -o $@  native-objs/xmlexport.o native-objs/parxml.o $(NATIVE_LIBS)

native-objs/parget: native-objs/parget.o
	gcc -o $@ $< $(NATIVE_LIBS)

native-objs/parset: native-objs/parset.o
	gcc -o $@ $< $(NATIVE_LIBS)

$(STAGE_DIR)/bin/native/xmlexport: $(STAGE_DIR)/bin/native native-objs/xmlexport
	if [ ! -h $(STAGE_DIR)/bin/native/xmlexport ]; then \
		ln -s $(CURDIR)/native-objs/xmlexport $@; \
	fi

$(STAGE_DIR)/bin/native/xmlimport: $(STAGE_DIR)/bin/native native-objs/xmlimport
	if [ ! -h $(STAGE_DIR)/bin/native/xmlimport ]; then \
		ln -s $(CURDIR)/native-objs/xmlimport $@; \
	fi

$(STAGE_DIR)/bin/native/parget: $(STAGE_DIR)/bin/native native-objs/parget
	if [ ! -h $(STAGE_DIR)/bin/native/parget ]; then \
		ln -s $(CURDIR)/native-objs/parget $@; \
	fi

$(STAGE_DIR)/bin/native/parset: $(STAGE_DIR)/bin/native native-objs/parset
	if [ ! -h $(STAGE_DIR)/bin/native/parset ]; then \
		ln -s $(CURDIR)/native-objs/parset $@; \
	fi


$(CURDIR)/platform-objs $(CURDIR)/native-objs $(STAGE_DIR)/bin/native:
	@ mkdir -p $@

--- NEW FILE: parget.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

#include <par/pardb.h>

void
print_usage(void)
{
    printf("\n-------\n");
    printf("parget [-h] -d <DB file> <node>\n\n");

    printf("[-h, --help] - print this screen\n");
    printf("[-d, --db] - The database to read from\n");
    printf("-------\n\n");
}

#define HAVE_DB_FILE 0x1
#define LIST_NODE 0x2

void
printValue(int type, void *value)
{

    switch (type) {

    case PAR_TEXT:
	printf("%s\n", (char *) value);
	break;

    case PAR_INT:
	printf("%d\n", *((int *) value));
	break;

    case PAR_FLOAT:
	printf("%f\n", *((double *) value));

    case PAR_BOOL:
	if (*((int *) value))
	    printf("TRUE\n");
	else
	    printf("FALSE\n");
	break;

    default:
	printf("\n");
	break;
    }
}

int
doStandard(db_handle * db, char *node)
{

    char *value;
    unsigned short type;
    int size = db_getDataSize(db, node);

    if (size == -1) {
	fprintf(stderr, "ERROR:  Internal error %d occured\n", pardb_errno);
	return (-1);
    }

    if (!size)
	return (0);

    /* The size will have the NULL already added to it */

    value = alloca(size);
    bzero(value, size);

    if (db_findNode(db, node, value, size, &type) == -1) {

	if (pardb_errno == PARDB_NOTFOUND)
	    fprintf(stderr, "ERROR:  Node %s was not found\n", node);
	else
	    fprintf(stderr, "ERROR:  Internal error %d occured\n",
		    pardb_errno);

	return (-1);
    }

    printValue(type, value);
    return (0);
}

int
doWildcard(db_handle * db, char *node)
{

    char **list;

    char *p;
    char *parent = alloca(strlen(node) + 1);

    int count, i;

    if (!parent)
	return (-1);
    strcpy(parent, node);

    p = strrchr(parent, '.');
    if (!p)
	return (-1);		/* We don't handle toplevel search yet */

    *p = 0;

    count = db_getChildCount(db, parent);

    if (count == -1)
	return (-1);
    if (count == 0)
	return (0);

    list = (char **) calloc(sizeof(char *) * count, 1);

    if (db_getChildList(db, parent, list, count) <= 0)
	return (-1);

    for (i = 0; i < count; i++) {
	char *child;

	child = alloca(strlen(parent) + strlen(list[i]) + 2);
	sprintf(child, "%s.%s", parent, list[i]);

	printf("%s: ", child);

	doStandard(db, child);
    }

    for (i = 0; i < count; i++)
	if (list[i])
	    free(list[i]);

    free(list);

    return (0);
}

int
main(int argc, char **argv)
{

    db_handle *db;

    unsigned char flags = 0;

    char *database_filename = 0;
    char *node;

    while (1) {
	signed char c;
	int option_index;

	static struct option long_options[] = {
	    {"help", 0, 0, 'h'},
	    {"db", 1, 0, 'd'},
	    {"list", 0, 0, 'l'},
	    {0, 0, 0, 0}
	};

	c = getopt_long(argc, argv, "d:h", long_options, &option_index);
	if (c == -1)
	    break;

	switch (c) {
	case 'h':
	    print_usage();
	    return (0);

	case 'd':
	    database_filename = alloca(strlen(optarg) + 1);
	    strcpy(database_filename, optarg);

	    flags |= HAVE_DB_FILE;
	    break;

	default:
	    print_usage();
	    return (-1);
	}
    }

    if (optind < argc) {
	node = alloca(strlen(argv[optind]) + 1);
	strcpy(node, argv[optind]);
    } else {
	fprintf(stderr, "ERROR: You must specific a node to search for\n");
	print_usage();
	return (-1);
    }

    if (!(flags & HAVE_DB_FILE)) {
	database_filename = db_getDefaultDB();
	if (!database_filename) {
	    fprintf(stderr,
		    "ERROR:  Could not determine the default database.\n");
	    print_usage();
	    return (-1);
	}
    }

    /* Open the file, search for the node, and output it to stdout */
    db = db_openDB(database_filename, PAR_DB_MODE_RDONLY);
    if (!db) {
	switch (pardb_errno) {
	case PARDB_NOFILE:
	    fprintf(stderr, "ERROR:  File %s does not exist.\n",
		    database_filename);
	    break;

	case PARDB_FILEERR:
	    fprintf(stderr, "ERROR:  Error while opening %s.\n",
		    database_filename);
	    break;

	case PARDB_BADDB:
	    fprintf(stderr, "ERROR:  %s is not a PAR database\n",
		    database_filename);
	    break;

	default:
	    fprintf(stderr,
		    "ERROR:  Internal error %d occured while opening %s\n",
		    pardb_errno, database_filename);
	    break;
	}

	return (-1);
    }

    /* We have the undocumented pleasure of allowing a wildcard as the leaf node */
    if (node[strlen(node) - 1] == '*')
	doWildcard(db, node);
    else
	doStandard(db, node);



    db_closeDB(db);
    return (0);
}




More information about the dslinux-commit mailing list