/*================================================== * open_database -- open database * forceopen: [in] flag to override reader/writer protection * dbpath: [in] database path to open *================================================*/ BOOLEAN open_database (INT alteration, STRING dbpath, INT *lldberr) { LLDATABASE lldb = lldb_alloc(); BOOLEAN rtn = FALSE; char fpath[MAXPATHLEN]; /* tentatively copy paths into gedlib module versions */ strupdate(&readpath_file, lastpathname(dbpath)); llstrncpy(fpath, dbpath, sizeof(fpath), 0); expand_special_fname_chars(fpath, sizeof(fpath), uu8); strupdate(&readpath, fpath); if (f_dbnotify) (*f_dbnotify)(readpath, TRUE); rtn = open_database_impl(lldb, alteration, lldberr); if (!rtn) { /* open failed so clean up, preserve lldberr */ int myerr = *lldberr; lldb_close(&lldb); *lldberr = myerr; } def_lldb = lldb; return rtn; }
/*=========================================== * 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); }
static FILE * ask_for_file_worker (STRING mode, STRING ttl, STRING *pfname, STRING *pfullpath, STRING path, STRING ext, DIRECTION direction) { FILE *fp; char prompt[MAXPATHLEN]; char fname[MAXPATHLEN]; int elen, flen; BOOLEAN rtn; make_fname_prompt(prompt, sizeof(prompt), ext); if (direction==INPUT) rtn = ask_for_input_filename(ttl, path, prompt, fname, sizeof(fname)); else rtn = ask_for_output_filename(ttl, path, prompt, fname, sizeof(fname)); if (pfname) { if (fname && fname[0]) *pfname = strdup(fname); else *pfname = 0; } if (pfullpath) *pfullpath = 0; /* 0 indicates we didn't try to open */ if (!rtn || !fname[0]) return NULL; if (!expand_special_fname_chars(fname, sizeof(fname), uu8)) { msg_error(_(qSfn2long)); return NULL; } ask_for_file_try: /* try name as given */ if (ISNULL(path)) { /* bare filename was given */ if ((fp = fopen(fname, mode)) != NULL) { if (pfname) strupdate(pfname, fname); return fp; } } else { /* fully qualified path was given */ if ((fp = fopenpath(fname, mode, path, ext, uu8, pfullpath)) != NULL) { return fp; } } /* try default extension */ if (ext) { elen = strlen(ext); flen = strlen(fname); if (elen<flen && path_match(fname+flen-elen, ext)) { ext = NULL; /* the file name has the extension already */ } else { /* add extension and go back and retry */ llstrapps(fname, sizeof(fname), uu8, ext); ext = NULL; /* only append extension once! */ goto ask_for_file_try; } } /* failed to open it, give up */ msg_error(_(qSnofopn), fname); return NULL; }