示例#1
0
/*=============================
 * isletter -- Check for letter
 * TODO: Fix for Unicode
 *===========================*/
BOOLEAN
isletter (INT c)
{
	if (opt_mychar) return mych_isalpha(c);
#ifndef OS_NOCTYPE
	return isalpha(c);
#else
	return isasciiletter(c);
#endif
}
示例#2
0
/*===============================================
 * is_path -- Is this a path (not a bare filename) ?
 *  ie, does this have any slashes in it?
 * (does not handle escaped slashes)
 *=============================================*/
BOOLEAN
is_path (CNSTRING dir)
{

	if (strchr(dir,LLCHRDIRSEPARATOR)) return TRUE;
#ifdef WIN32
	/* windows \ or / is path separator. */
	if (strchr(dir,'/')) return TRUE;
	if (dir[0] && dir[1]==':' && isasciiletter(dir[0])) {
		return TRUE;
	}
#endif
	return FALSE;
}
示例#3
0
/*===============================================
 * is_absolute_path -- Is this an absolute path ?
 *  handle WIN32 characters, and ~ homedir references
 *=============================================*/
BOOLEAN
is_absolute_path (CNSTRING dir)
{
	/* if it starts with a slash, it's absolute */
	if (is_dir_sep(dir[0])) return TRUE;
	/* if it starts with a dot, it's relative, but not relative
	to search path, only to current directory -- as in shell logic 
	so we say it is absolute */
	if (dir[0] == '.') return TRUE;
	/* if it starts with ~, it is a reference to an absolute home dir */
	if (dir[0] == '~') return TRUE;
#ifdef WIN32
	/* if it starts with a drive letter, it's absolute */
	if (dir[0] && dir[1]==':' && isasciiletter(dir[0])) {
		return TRUE;
	}
#endif
	return FALSE;
}	
示例#4
0
/*===========================================
 * filepath -- Find file in sequence of paths
 *  handles NULL in either argument
 *  returns alloc'd buffer
 * Warning: if called with mode other than "r" this may not 
 *         do what you want, because 1) if file is not found, it appends ext.
 *         and 2) file always goes in 1st specified directory of path unless
 *         name is absolute or ./something
 *=========================================*/
STRING
filepath (CNSTRING name, CNSTRING mode, CNSTRING path, CNSTRING  ext, INT utf8)
{
	char buf1[MAXPATHLEN], buf2[MAXPATHLEN];
	STRING p, q;
	INT nlen, elen;

	if (ISNULL(name)) return NULL;
	if (ISNULL(path)) return strsave(name);
	nlen = strlen(name);
	if (ext && *ext) {
		elen = strlen(ext);
		if ((nlen > elen) && path_match(name+nlen-elen, ext)) {
			ext = NULL;
			elen = 0;
		}
	}
	else { ext = NULL; elen = 0; }
	/*  at this point ext is non-null only if name doesn't 
	 *  end in ext.  I.E. we need to check for name + ext and name
	 */

	if (nlen + strlen(path) + elen >= MAXLINELEN) return NULL;

	/* for absolute and relative path names we first check the
	 * pathname for validity relative to the current directory
	 */
	if (is_path(name)) {
		/* If this is a path, i.e. it has multiple path elements
		 * use the name as is first.  So absolute paths don't
		 * get resolved by appending search paths.
		 */
		if (ext) {
			strcpy(buf1,name);
			nlen = strlen(buf1);
			strcat(buf1, ext);
			if (access(buf1, 0) == 0) return strsave(buf1);
			buf1[nlen] = '\0'; /* remove extension */
			if (access(buf1, 0) == 0) return strsave(buf1);
		}
		if (access(name, 0) == 0) return strsave(name);
		/* fail if get here and name begins with a / or ./
		 * as we didn't find the file.
		 * however let foo/bar sneak thru, so we allow access
		 * to files in subdirectories of the search path if 
		 * named in the filename.
		 */
		if (is_dir_sep(name[0]) || (name[0] == '.' && is_dir_sep(name[1])))
			return strsave(name);
#ifdef WIN32
		if (name[0] && name[1]==':' && isasciiletter(name[0])) {
			return strsave(name);
		}
#endif
	}

	/* it is a relative path, so search for it in search path */
	strcpy(buf1, path);
	zero_separate_path(buf1);
	p = buf1;
	while (*p) {
		q = buf2;
		strcpy(q, p);
		expand_special_fname_chars(buf2, sizeof(buf2), utf8);
		q += strlen(q);
		if (q>buf2 && !is_dir_sep(q[-1])) {
			strcpy(q, LLSTRDIRSEPARATOR);
			q++;
		}
		strcpy(q, name);
		if (ext) {
			nlen = strlen(buf2);
			strcat(buf2, ext);
			if (access(buf2, 0) == 0) return strsave(buf2);
			buf2[nlen] = '\0'; /* remove extension */
		}
		if (access(buf2, 0) == 0) return strsave(buf2);
		p += strlen(p);
		p++;
	}
	if (mode[0] == 'r') return NULL;
	p = buf1;
	q = buf2;
	strcpy(q, p);
	expand_special_fname_chars(buf2, sizeof(buf2), utf8);
	q += strlen(q);
	if (q>buf2 && !is_dir_sep(q[-1])) {
		strcpy(q, LLSTRDIRSEPARATOR);
		q++;
	}
	strcpy(q, name);
	if (ext) strcat(q, ext);
	return strsave(buf2);
}
示例#5
0
/*==================================
 * main -- Main routine of LifeLines
 *================================*/
int
main (int argc, char **argv)
{
	extern char *optarg;
	extern int optind;
	char * msg;
	int c;
	BOOLEAN ok=FALSE;
	STRING dbrequested=NULL; /* database (path) requested */
	STRING dbused=NULL; /* database (path) found */
	BOOLEAN forceopen=FALSE, lockchange=FALSE;
	char lockarg = 0; /* option passed for database lock */
	INT alteration=0;
	LIST exprogs=NULL;
	TABLE exargs=NULL;
	STRING progout=NULL;
	BOOLEAN graphical=TRUE;
	STRING configfile=0;
	STRING crashlog=0;
	int i=0;

	/* initialize all the low-level library code */
	init_stdlib();

#if HAVE_SETLOCALE
	/* initialize locales */
	setlocale(LC_ALL, "");
#endif /* HAVE_SETLOCALE */
	
	/* capture user's default codeset */
	ext_codeset = strsave(ll_langinfo());
	/* TODO: We can use this info for default conversions */

#if ENABLE_NLS
	/* setup gettext translation */
	ll_bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
#endif

	save_original_locales();
	load_usage();

	/* handle conventional arguments --version and --help */
	/* needed for help2man to synthesize manual pages */
	for (i=1; i<argc; ++i) {
		if (!strcmp(argv[i], "--version")
			|| !strcmp(argv[i], "-v")) {
			print_version("llexec");
			return 0;
		}
		if (!strcmp(argv[i], "--help")
			|| !strcmp(argv[i], "-h")
			|| !strcmp(argv[i], "-?")) {
			print_usage();
			return 0;
		}
	}

	/* Parse Command-Line Arguments */
	opterr = 0;	/* turn off getopt's error message */
	while ((c = getopt(argc, argv, "adkrwil:fntc:Fu:x:o:zC:I:vh?")) != -1) {
		switch (c) {
		case 'c':	/* adjust cache sizes */
			while(optarg && *optarg) {
				if(isasciiletter((uchar)*optarg) && isupper((uchar)*optarg))
					*optarg = tolower((uchar)*optarg);
				if(*optarg == 'i') {
					INT icsz_indi=0;
					sscanf(optarg+1, "%ld,%ld", &csz_indi, &icsz_indi);
				}
				else if(*optarg == 'f') {
					INT icsz_fam=0;
					sscanf(optarg+1, "%ld,%ld", &csz_fam, &icsz_fam);
				}
				else if(*optarg == 's') {
					INT icsz_sour=0;
					sscanf(optarg+1, "%ld,%ld", &csz_sour, &icsz_sour);
				}
				else if(*optarg == 'e') {
					INT icsz_even=0;
					sscanf(optarg+1, "%ld,%ld", &csz_even, &icsz_even);
				}
				else if((*optarg == 'o') || (*optarg == 'x')) {
					INT icsz_othr=0;
					sscanf(optarg+1, "%ld,%ld", &csz_othr, &icsz_othr);
				}
				optarg++;
				while(*optarg && isdigit((uchar)*optarg)) optarg++;
				if(*optarg == ',') optarg++;
				while(*optarg && isdigit((uchar)*optarg)) optarg++;
			}
			break;
#ifdef FINNISH
# ifdef FINNISHOPTION
		case 'F':	/* Finnish sorting order [toggle] */
			opt_finnish = !opt_finnish;
			/*
			TO DO - need to mark Finnish databases, as 
			name records are not interoperable, because of
			different soundex encoding
			2001/02/17, Perry Rapp
			*/
			break;
# endif
#endif
		case 'a':	/* debug allocation */
			alloclog = TRUE;
			break;
		case 'd':	/* debug = no signal catchers */
			debugmode = TRUE;
			break;
		case 'k':	/* don't show key values */
			keyflag = FALSE;
			break;
		case 'r':	/* request for read only access */
			readonly = TRUE;
			break;
		case 'w':	/* request for write access */
			writeable = TRUE;
			break;
		case 'i': /* immutable access */
			immutable = TRUE;
			readonly = TRUE;
			break;
		case 'l': /* locking switch */
			lockchange = TRUE;
			lockarg = *optarg;
			break;
		case 'f':	/* force database open in all cases */
			forceopen = TRUE;
			break;
		case 'n':	/* use non-traditional family rules */
			traditional = FALSE;
			break;
		case 't': /* show lots of trace statements for debugging */
			prog_trace = TRUE;
			break;
		case 'x': /* execute program */
			if (!exprogs) {
				exprogs = create_list2(LISTDOFREE);
			}
			push_list(exprogs, strdup(optarg ? optarg : ""));
			break;
		case 'I': /* program arguments */
			{
				STRING optname=0, optval=0;
				parse_arg(optarg, &optname, &optval);
				if (optname && optval) {
					if (!exargs) {
						exargs = create_table_str();
					}
					insert_table_str(exargs, optname, optval);
				}
				strfree(&optname);
				strfree(&optval);
			}
			break;
		case 'o': /* output directory */
			progout = optarg;
			break;
		case 'z': /* nongraphical box */
			graphical = FALSE;
			break;
		case 'C': /* specify config file */
			configfile = optarg;
			break;
		case 'v': /* show version */
			showversion = TRUE;
			goto usage;
			break;
		case 'h': /* show usage */
		case '?': /* show usage */
			showversion = TRUE;
			showusage = TRUE;
			goto usage;
			break;
		}
	}

prompt_for_db:

	/* catch any fault, so we can close database */
	if (debugmode)
		stdstring_hardfail();
	else
		set_signals();

	platform_init();
	set_displaykeys(keyflag);
	/* initialize options & misc. stuff */
	llgettext_set_default_localedir(LOCALEDIR);
	if (!init_lifelines_global(configfile, &msg, &main_db_notify)) {
		llwprintf("%s", msg);
		goto finish;
	}
	/* setup crashlog in case init_screen fails (eg, bad menu shortcuts) */
	crashlog = getlloptstr("CrashLog_llexec", NULL);
	if (!crashlog) { crashlog = "Crashlog_llexec.log"; }
	crash_setcrashlog(crashlog);
	init_interpreter(); /* give interpreter its turn at initialization */

	/* Validate Command-Line Arguments */
	if ((readonly || immutable) && writeable) {
		llwprintf(_(qSnorwandro));
		goto finish;
	}
	if (forceopen && lockchange) {
		llwprintf(_(qSnofandl));
		goto finish;
	}
	if (lockchange && lockarg != 'y' && lockarg != 'n') {
		llwprintf(_(qSbdlkar));
		goto finish;
	}
	if (forceopen)
		alteration = 3;
	else if (lockchange) {
		if (lockarg == 'y')
			alteration = 2;
		else
			alteration = 1;
	}
	c = argc - optind;
	if (c > 1) {
		showusage = TRUE;
		goto usage;
	}

	/* Open database, prompting user if necessary */
	if (1) {
		STRING errmsg=0;
		if (!alldone && c>0) {
			dbrequested = strsave(argv[optind]);
		} else {
			strupdate(&dbrequested, "");
		}
		if (!select_database(dbrequested, alteration, &errmsg)) {
			if (errmsg) {
				llwprintf(errmsg);
			}
			alldone = 0;
			goto finish;
		}
	}

	/* Start Program */
	if (!init_lifelines_postdb()) {
		llwprintf(_(qSbaddb));
		goto finish;
	}
	/* does not use show module */
	/* does not use browse module */
	if (exargs) {
		set_cmd_options(exargs);
		release_table(exargs);
		exargs = 0;
	}
	if (exprogs) {
		BOOLEAN picklist = FALSE;
		BOOLEAN timing = FALSE;
		interp_main(exprogs, progout, picklist, timing);
		destroy_list(exprogs);
	} else {
		/* TODO: prompt for report filename */
	}
	/* does not use show module */
	/* does not use browse module */
	ok=TRUE;

finish:
	/* we free this not because we care so much about these tiny amounts
	of memory, but to ensure we have the memory management right */
	/* strfree frees memory & nulls pointer */
	if (dbused) strfree(&dbused);
	strfree(&dbrequested);
	strfree(&readpath_file);
	shutdown_interpreter();
	close_lifelines();
	shutdown_ui(!ok);
	if (alldone == 2)
		goto prompt_for_db; /* changing databases */
	termlocale();
	strfree(&ext_codeset);

usage:
	/* Display Version and/or Command-Line Usage Help */
	if (showversion) { print_version("llexec"); }
	if (showusage) puts(usage_summary);

	/* Exit */
	return !ok;
}