/* Copyright (c) 2000-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dkapp.c The dkapp module. */ $(trace-include) #include #include "dk.h" #include "dktypes.h" #include "dkmem.h" #include "dksf.h" #include "dkma.h" #include "dkstr.h" #include "dksto.h" #include "dklogc.h" #include "dkstt.h" #include "dkstream.h" #include "dkcp.h" #include "dkenc.h" #if DK_TIME_WITH_SYS_TIME #include #include #else #if DK_HAVE_SYS_TIME_H #include #else #if DK_HAVE_TIME_H #include #endif #endif #endif #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_UNISTD_H #include #endif /** Inside the dkapp.c module. */ #define DK_APP_C 1 #include "dkapp.h" #include "dkrandc.h" #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_WINREG_H #include "dkwin.h" #endif #if DK_HAVE_SYSLOG_H #include #endif #if DK_HAVE_CTYPE_H #include #endif #if DK_HAVE_ZLIB_H #include #endif /** Default system configuration directory on *x systems. */ static char unix_sysconfdir[] = { DK_SYSCONFDIR }; /** Pointer to character buffer. */ typedef char *CHARPTR; /** String table entry. */ typedef struct { char *name; /**< Name of string table. */ dk_stt_t *st; /**< Pointer to string table structure. */ } stt_entry; /** Flag: Run silently. */ static int set_silent = 0; /** Preference key: Logging disabled. */ static char key_log_off[]= { "/log/off" }; /** Encoding: UTF-8. */ static char str_utf8_a[] = { "utf-8" }; /** Variant of encoding: UTF-8 */ static char str_utf8_b[] = { "utf8" }; /** File open mode: Read. */ static char str_r[] = { "r" }; $* Check whether or not the command line option --/log/off=yes was used to suppress logging to stdout/stderr. $* int dkapp_silence_check DK_P2(int,argc,char **,argv) { int back = 0; int i; char *cptr, *vptr; for(i = 1; i < argc; i++) { cptr = argv[i]; vptr = NULL; if(cptr[0] == '-') { if(cptr[1] == '-') { vptr = dkstr_chr(cptr, '='); if(vptr) { *vptr = (char)0; } if(strcmp(&(cptr[2]), key_log_off) == 0) { if(vptr) { if(dkstr_is_on(&(vptr[1]))) { back = 1; } } else { back = 1; } } if(vptr) { *vptr = '='; } } } } return back; } /** Release string table. @param s String table. */ static void stt_entry_free DK_P1(stt_entry *,s) { char *cptr; cptr = s->name; if(cptr) { dk_delete(cptr); } s->name = NULL; if(s->st) { dkstt_close(s->st); } s->st = NULL; dk_delete(s) ; } /** Compare string table container entries. @param p1 Left string table. @param p2 Right string table. @param crit Comparison criteria (0=table/table, 1=table/name). @return Comparison result. */ static int stt_entry_comp DK_P3(void *,p1,void *,p2,int,crit) { int back = 0; stt_entry *s1, *s2; $? "+ stt_entry_comp %s %s", TR_PTR(p1), TR_PTR(p2) if(p1 && p2) { switch(crit) { case 1: { s1 = (stt_entry *)p1; if(s1->name) { back = strcmp((s1->name),((char *)p2)); } else { back = -1; } } break; default: { s1 = (stt_entry *)p1; s2 = (stt_entry *)p2; if(s1->name) { if(s2->name) { back = strcmp((s1->name),(s2->name)); } else { back = 1; } } else { if(s2->name) { back = -1; } } } break; } } $? "- stt_entry_comp %d", back return back; } /** The "all" scope is used when retrieving preferences from the registry. */ static char all_files[] = { "all" }; /** The general preferences scope. */ static char scope_all[] = { "*" }; /** Dot used to construct file names. */ static char dot[] = { "." }; /** Name "app". */ static char app[] = { "app" }; /** Suffix for log files. */ static char suffix_log[] = { "log" }; /** Suffix for temporary directories. */ static char dot_tmp[] = { ".TMP" }; #if DK_HAVE_WINREG_H /** Registry key name. */ static char hklm[] = { "Software\\DkApp" }; /** Registry key name. */ static char hkcu[] = { "SOFTWARE\\DkApp" }; /** Backslash. */ static char backslash[] = { "\\" }; #endif /** Separator between path components. */ static char fn_sep[] = { #if DK_HAVE_FEATURE_BACKSLASH "\\" #else "/" #endif }; /** Name of the bin subdirectory. */ static char bin_dir[] = { "bin" }; /** Name of the share subdirectory. */ static char share_dir[] = { "share" }; /** Name of configuration file subdirectory in HOME. */ static char defaults_sub[] = { #if DK_HAVE_DOTFILENAMES ".defaults" #else "defaults" #endif }; /** File name for configuration file. */ static char appdef[] = { "appdef" }; $* Comparison of preference entries. cr = 0: pref entry / pref entry cr = 1: pref entry / entry name as string $* /** Delete preference entry, release memory. @param p Preference entry to delete. */ void dkpref_delete DK_P1(dk_preference_t *, p) { char *x; $? "+ dkpref_delete %s", TR_PTR(p) if(p) { $? ". %s %s %d", TR_STR(p->n), TR_STR(p->v), p->p x = p->v; if(x) dk_delete(x); x = p->n; if(x) dk_delete(x); p->p = 0; p->v = NULL; p->n = NULL; dk_delete(p); } $? "- dkpref_delete" } /** Create preference entry, allocate memory. @param name Preference name. @param value Preference value. @param prio Preference priority. @return Pointer to new preference entry on success, NULL on error. */ dk_preference_t * dkpref_new DK_P3(char *, name, char *, value, int, prio) { dk_preference_t *back = NULL; $? "+ dkpref_new %s %s %d", TR_STR(name), TR_STR(value), prio if(name && value) { back = dk_new(dk_preference_t,1); if(back) { back->n = dkstr_dup(name); back->v = dkstr_dup(value); back->p = prio; if(!((back->v) && (back->n))) { dkpref_delete(back); back = NULL; } } } $? "- dkpref_new %s", TR_PTR(back) return back; } /** Compare two preference entries. @param p1 Left preference entry. @param p2 Right preference entry. @param cr Comparison criteria (0=pref/pref, 1=pref/name). @return Comparison result. */ int dkapp_pref_compare DK_P3(void *, p1, void *, p2, int, cr) { int back = 0; $? "+ dkapp_pref_compare %s %s %d", TR_PTR(p1), TR_PTR(p2), cr if(p1 && p2) { switch(cr) { case 1: { /* search for specific entry */ $? ". entry %s / string %s", TR_STR(((dk_preference_t *)p1)->n), TR_STR(p2) back = strcmp((((dk_preference_t *)p1)->n),(char *)p2); } break; default: { /* sort entries in container */ $? ". entry %s / entry %s", TR_STR(((dk_preference_t *)p1)->n), TR_STR(((dk_preference_t *)p2)->n) back = strcmp((((dk_preference_t *)p1)->n),(((dk_preference_t *)p2)->n)); } break; } } $? "- dkapp_pref_compare %d", back return back; } /** Add a preference to the list. @param s Preferences storage. @param si Iterator for \a si. @param n Preference name. @param v Preference value. @param p 0=general config file, 2=app-specific file, 4=file from user home directory. */ static void add_pref_to_list DK_P5(dk_storage_t *,s, dk_storage_iterator_t *,si,char *,n, char *,v, int,p) { dk_preference_t *pptr; char *cptr; $? "+ add_pref_to_list" if(s && si && n && v) { pptr = (dk_preference_t *)dksto_it_find_like(si,n,1); if(pptr) { $? ". replace value" if(p >= pptr->p) { cptr = pptr->v; if(cptr) dk_delete(cptr); pptr->v = dkstr_dup(v); pptr->p = p; } } else { $? ". add new entry" pptr = dkpref_new(n,v,p); if(pptr) { if(!dksto_add(s,pptr)) { dkpref_delete(pptr); } } } } $? "- add_pref_to_list" } $* Read configuration from a file. To select only entries matching current user name, application name and host name these names are specified in un, an and hn. $* /** Read configuration from a file. @param s Storage to save settings to. @param si Iterator for \a s. @param fn File to read. @param un user name. @param an Application name. @param hn host name. @param prio 0=general config file, 2=app-specific file, 4=file from user home directory. */ static void read_cfg DK_P7(dk_storage_t *, s, dk_storage_iterator_t *, si, char *, fn, char *, un, char *, an, char *, hn, int, prio) { FILE *inputfile; char inputline[256], *cp1, *cp2, *cp3; int can_continue; int p_to_save; int use_entries; $? "+ read_cfg \"%s\" %s %s %s %d", TR_STR(fn), TR_STR(un), TR_STR(an), TR_STR(hn), prio if(fn && s && si) { inputfile = dksf_fopen(fn, str_r); if(inputfile) { $? ". file opened" can_continue = 1; use_entries = 1; p_to_save = 0; while(can_continue) { if(fgets(inputline,sizeof(inputline),inputfile)) { cp2 = cp3 = NULL; cp1 = dkstr_start(inputline, NULL); if(cp1) { cp2 = dkstr_chr(cp1, '#'); if(cp2) { *cp2 = '\0'; } cp1 = dkstr_start(cp1, NULL); if(cp1) { $? ". processing input line %s", inputline if(*cp1 == '[') { use_entries = 0; p_to_save = 0; cp2 = dkstr_rchr(cp1, ']'); if(cp2) { *cp2 = '\0'; cp1++; cp1 = dkstr_start(cp1, NULL); if(cp1) { dkstr_chomp(cp1, NULL); cp2 = dkstr_chr(cp1, '/'); if(cp2) { *(cp2++) = '\0'; cp3 = dkstr_chr(cp2, '/'); if(cp3) { *(cp3++) = '\0'; } } switch(prio) { case 0: { if(cp1) { if(strcmp(cp1, scope_all) == 0) { use_entries = 1; } else { if(un) { if(strcmp(cp1, un) == 0) { use_entries = 1; p_to_save = 4; } } } if(use_entries) { use_entries = 0; if(cp2) { if(strcmp(cp2, scope_all) == 0) { use_entries = 1; } else { if(an) { if(strcmp(cp2, an) == 0) { use_entries = 1; p_to_save |= 2; } } } if(use_entries) { use_entries = 0; if(cp3) { if(strcmp(cp3, scope_all) == 0) { use_entries = 1; } else { if(hn) { if(strcmp(cp3, hn) == 0) { use_entries = 1; p_to_save |= 1; } } } } else { use_entries = 1; } } } else { use_entries = 1; } } } else { use_entries = 1; } } break; case 2: { if(cp1) { if(strcmp(cp1, scope_all) == 0) { use_entries = 1; } else { if(un) { if(strcmp(cp1, un) == 0) { use_entries = 1; p_to_save |= 4; } } } if(use_entries) { use_entries = 0; if(cp2) { if(strcmp(cp2, scope_all) == 0) { use_entries = 1; } else { if(hn) { if(strcmp(cp2, hn) == 0) { use_entries = 1; p_to_save |= 1; } } } } else { use_entries = 1; } } } else { use_entries = 1; } } break; case 4: { if(cp1) { if(strcmp(cp1, scope_all) == 0) { use_entries = 1; } else { if(an) { if(strcmp(cp1, an) == 0) { use_entries = 1; p_to_save |= 2; } } } if(use_entries) { use_entries = 0; if(cp2) { if(strcmp(cp2, scope_all) == 0) { use_entries = 1; } else { if(hn) { if(strcmp(cp2, hn) == 0) { use_entries = 1; p_to_save |= 1; } } } } else { use_entries = 1; } } } else { use_entries = 1; } } break; case 6: { if(cp1) { if(strcmp(cp1, scope_all) == 0) { use_entries = 1; } else { if(hn) { if(strcmp(cp1, hn) == 0) { use_entries = 1; p_to_save |= 1; } } } } else { use_entries = 1; } } break; } } } } else { /* if(*cp1 == '[') */ if(use_entries) { cp2 = dkstr_chr(cp1, '='); if(cp2) { *(cp2++) = '\0'; cp2 = dkstr_start(cp2, NULL); if(cp2) { cp1 = dkstr_start(cp1, NULL); if(cp1) { dkstr_chomp(cp1, NULL); dkstr_chomp(cp2, NULL); add_pref_to_list(s,si,cp1,cp2,(p_to_save | prio)); } } } } } } } } else { can_continue = 0; } } fclose(inputfile); } } $? "- read_cfg" } /** Initialize application structure. @param a Application. */ static void app_init_empty DK_P1(dk_app_t *, a) { $? "= app_init_empty %s", TR_PTR(a) if(a) { (a->td).l = 0UL; (a->a).o.argc = 0; (a->a).o.argv = NULL; (a->a).a.argc = 0; (a->a).a.argv = NULL; (a->n).u = NULL; (a->n).a = NULL; (a->n).h = NULL; (a->n).g = NULL; (a->d).h = NULL; (a->d).t = NULL; (a->d).a = NULL; (a->d).s = NULL; (a->d).pt = NULL; (a->d).etc = NULL; (a->p).c = NULL; (a->p).ci = NULL; (a->p).a = NULL; (a->p).ai = NULL; #if DK_HAVE_WINREG_H (a->p).what = 0; #else (a->p).u = NULL; (a->p).ui = NULL; (a->p).s = NULL; (a->p).si = NULL; #endif (a->p).unc = 0; (a->p).prf = 0; (a->x).f = NULL; (a->x).d = NULL; (a->l).max = DK_LOG_LEVEL_IGNORE; (a->l).nostdio = 0; (a->l).o.m = DK_LOG_LEVEL_NONE; (a->l).o.f = 0; (a->l).o.ide_type = 0; (a->l).e.m = DK_LOG_LEVEL_WARNING; (a->l).e.f = 0; (a->l).e.ide_type = 0; (a->l).f.m = DK_LOG_LEVEL_WARNING; (a->l).f.k = DK_LOG_LEVEL_ERROR; (a->l).f.f = 3; (a->l).f.t = NULL; (a->l).f.n = NULL; (a->l).f.ide_type = 0; #if DK_HAVE_SYSLOG (a->l).s.m = DK_LOG_LEVEL_NONE; (a->l).s.i = NULL; (a->l).s.f = 0; (a->l).s.o = 0; #endif (a->l).o.c = NULL; (a->l).e.c = NULL; (a->l).f.c = NULL; (a->l).ef.n = NULL; (a->l).ef.lineno = 0UL; (a->loc).l = NULL; (a->loc).r = NULL; (a->loc).e = NULL; (a->loc).s = NULL; (a->loc).si = NULL; (a->loc).es = DK_APP_ENCODING_DEFAULT; a->relaxed_fopen_check = 0; a->keep_temp_dir = DK_LOG_LEVEL_NONE; (a->random).prng_type = DK_RAND_TYPE_NONE; (a->random).seed_file_name = NULL; } } #if DK_HAVE_WINREG_H /** Colon. */ static char colon[] = { ":" }; /** Slash. */ static char slash[] = { "/" }; #endif $* Set a preference. For UNIX/Linux the preference is kept in memory until the application is finished, when shutting down the application the configuration file HOME/.defaults/app_name is rewritten if necessary. Preference changes on Windows systems go directly to the registry. $* int dkapp_set_pref DK_P3(dk_app_t *,a,char *,key,char *,value) { int back = 0; #if DK_HAVE_WINREG_H char keybuffer[256]; #endif $? "+ dkapp_set_pref %s %s %s", TR_PTR(a), TR_STR(key), TR_STR(value) if(a && key && value) { (a->p).prf = 1; if(((a->p).a) && ((a->p).ai)) { add_pref_to_list(((a->p).a), ((a->p).ai), key, value, 6); back = 1; } #if DK_HAVE_WINREG_H if(((a->n).h) && (((a->p).what) & 8)) { if(strlen(key) < sizeof(keybuffer)) { strcpy(keybuffer, key); RegSetValueExA( (a->p).hkcu_app, keybuffer, 0, REG_SZ, value, (strlen(value) + 1) ); } } #endif } $? "- dkapp_set_pref %d", back return back; } int dkapp_get_pref_env DK_P6(dk_app_t *,a,char *,key,char *,b,size_t,lgt,int,excl, char *,ep) { int back = 0; int found; int where; int can_use_this; char *evptr; #if DK_HAVE_WINREG_H char keybuffer[256]; LONG retval; DWORD dwType, sz; HKEY thekey; int passno; char *namea, *nameu, *nameh; #else dk_preference_t *pp1, *pp2; #endif dk_preference_t *pptr; $? "+ dkapp_get_pref %s %s %s %u %d", TR_PTR(a), TR_STR(key), TR_PTR(b), lgt, excl if((a) && (key) && (b) && (lgt)) { $? ". args ok" found = 0; /* check programs own setting */ if(!(excl & DK_APP_PREF_EXCL_PROG)) { if(((a->p).a) && ((a->p).ai)) { pptr = (dk_preference_t *)dksto_it_find_like((a->p).ai, key, 1); if(pptr) { found = 1; if(pptr->v) { if(lgt > strlen(pptr->v)) { strcpy(b, pptr->v); back = 1; } } } } } /* check command line */ if((found == 0) && (!(excl & DK_APP_PREF_EXCL_CMD))) { if(((a->p).c) && ((a->p).ci)) { pptr = (dk_preference_t *)dksto_it_find_like((a->p).ci, key, 1); if(pptr) { found = 1; if(pptr->v) { if(lgt > strlen(pptr->v)) { strcpy(b, pptr->v); back = 1; } } } } } if((found == 0) && (ep != NULL)) { evptr = getenv(ep); if(evptr) { if(strlen(evptr) < lgt) { strcpy(b, evptr); back = found = 1; } } } /* check preferences system */ if(found == 0) { where = 15; while((where >= 0) && (found == 0)) { can_use_this = 1; if(where & 1) { // user setting if(excl & DK_APP_PREF_EXCL_USER) can_use_this = 0; } else { // system setting if(excl & DK_APP_PREF_EXCL_SYSTEM) can_use_this = 0; switch(where) { case 7: case 5: case 3: case 1: { can_use_this = 0; } break; } } if(can_use_this) { #if DK_HAVE_WINREG_H /* retrieve preferences from registry */ nameu = ((where & 8) ? (a->n).u : all_files); namea = ((where & 4) ? (a->n).a : all_files); nameh = ((where & 2) ? (a->n).h : all_files); if(!(nameu)) nameu = all_files; if(!(namea)) namea = all_files; if(!(nameh)) nameh = all_files; passno = 0; while((passno < 2) && (found == 0)) { can_use_this = 0; switch(where) { case 15: { if(passno) { if((a->p).what & 4) { if((strlen(key) + strlen(namea) + strlen(nameh) + 2) < sizeof(keybuffer)) { can_use_this = 1; strcpy(keybuffer, namea); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hkcu_all; } } } else { if((a->p).what & 8) { if((strlen(key) + strlen(nameh) + 1) < sizeof(keybuffer)) { can_use_this = 1; strcpy(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hkcu_app; } } } } break; case 14: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(nameu) + strlen(namea) + strlen(nameh) + 3) < sizeof(keybuffer)) { strcpy(keybuffer, nameu); strcat(keybuffer, slash); strcat(keybuffer, namea); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } else { if((a->p).what & 2) { if((strlen(key) + strlen(nameu) + strlen(nameh) + 2) < sizeof(keybuffer)) { strcpy(keybuffer, nameu); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_app; can_use_this = 1; } } } } break; case 13: { if(passno) { if((a->p).what & 4) { if((strlen(key) + strlen(namea) + 1) < sizeof(keybuffer)) { strcpy(keybuffer, namea); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hkcu_all; can_use_this = 1; } } } else { if((a->p).what & 8) { if(strlen(key) < sizeof(keybuffer)) { strcpy(keybuffer, key); thekey = (a->p).hkcu_app; can_use_this = 1; } } } } break; case 12: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(nameu) + strlen(namea) + 2) < sizeof(keybuffer)) { strcpy(keybuffer, namea); strcat(keybuffer, slash); strcat(keybuffer, namea); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } else { if((a->p).what & 2) { if((strlen(key) + strlen(nameu) + 1) < sizeof(keybuffer)) { strcpy(keybuffer, nameu); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_app; can_use_this = 1; } } } } break; case 11: { if(passno) { if((a->p).what & 4) { if((strlen(key) + strlen(all_files) + strlen(nameh) + 2) < sizeof(keybuffer)) { strcpy(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hkcu_all; can_use_this = 1; } } } } break; case 10: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(nameu) + strlen(all_files) + strlen(nameh) + 3) < sizeof(keybuffer)) { strcpy(keybuffer, nameu); strcat(keybuffer, slash); strcat(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } } break; case 9: { if(passno) { if((a->p).what & 4) { if(strlen(key) < sizeof(keybuffer)) { strcpy(keybuffer, key); thekey = (a->p).hkcu_all; can_use_this = 1; } } } } break; case 8: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(nameu) + 1) < sizeof(keybuffer)) { strcpy(keybuffer, nameu); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } } break; case 6: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(all_files) + strlen(namea) + strlen(nameh) + 3) < sizeof(keybuffer)) { strcpy(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, namea); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } else { if((a->p).what & 2) { if((strlen(key) + strlen(all_files) + strlen(nameh) + 2) < sizeof(keybuffer)) { strcpy(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_app; can_use_this = 1; } } } } break; case 4: { if(passno) { if((a->p).what & 1) { if((strlen(key) + strlen(all_files) + strlen(namea) + 2) < sizeof(keybuffer)) { strcpy(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, namea); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } else { if((a->p).what & 2) { if(strlen(key) < sizeof(keybuffer)) { strcpy(keybuffer, key); thekey = (a->p).hklm_app; can_use_this = 1; } } } } break; case 2: { if(passno) { if((a->p).what & 1) { if((strlen(key) + 2 * strlen(all_files) + strlen(nameh) + 3) < sizeof(keybuffer)) { strcpy(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, all_files); strcat(keybuffer, slash); strcat(keybuffer, nameh); strcat(keybuffer, colon); strcat(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } } break; default: { if(passno) { if((a->p).what & 1) { if(strlen(key) < sizeof(keybuffer)) { strcpy(keybuffer, key); thekey = (a->p).hklm_all; can_use_this = 1; } } } } break; } if(can_use_this) { sz = lgt; retval = RegQueryValueExA( thekey, keybuffer, NULL, &dwType, b, &sz ); if(retval == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(sz < lgt) { b[sz] = '\0'; back = 1; found = 1; } } } } passno++; } #endif } where--; } #if !DK_HAVE_WINREG_H pp1 = NULL; pp2 = NULL; if(!(excl & DK_APP_PREF_EXCL_SYSTEM)) { if(((a->p).s) && ((a->p).si)) { pp1 = (dk_preference_t *)dksto_it_find_like((a->p).si, key, 1); if(pp1) { if(pp1->v) { if(strlen(pp1->v) < lgt) { strcpy(b, pp1->v); back = 1; found = pp1->p; } } } } } if(!(excl & DK_APP_PREF_EXCL_USER)) { if(((a->p).u) && ((a->p).ui)) { pp1 = (dk_preference_t *)dksto_it_find_like((a->p).ui, key, 1); if(pp1) { if(pp1->p >= found) { if(pp1->v) { if(strlen(pp1->v) < lgt) { strcpy(b, pp1->v); back = 1; found = pp1->p; } } } } } } #endif } } $? "- dkapp_get_pref %d", back return back; } int dkapp_get_pref DK_P5(dk_app_t *,a,char *,key,char *,b,size_t,lgt,int,excl) { int back = 0; back = dkapp_get_pref_env(a, key, b, lgt, excl, NULL); return back; } /** Log level names. */ static char *log_level_strings[] = { (char *)"n$one", (char *)"pa$nic", (char *)"f$atal", (char *)"e$rror", (char *)"warn$ing", (char *)"i$nfo", (char *)"pr$ogress", (char *)"d$ebug", NULL }; /** Translate log level from string to numeric value. @param str Log level name. @return Numeric representation of the log level. */ static int get_log_level DK_P1(char *,str) { int back = -1; if(str) { back = dkstr_array_abbr(log_level_strings, str, '$', 0); } return back; } /** Preference key: Use IDE style when logging to file. */ static char log_file_ide[] = { "/log/file/ide" }; /** Preference key: Use IDE style when logging to stdout. */ static char log_stdout_ide[] = { "/log/stdout/ide" }; /** Preference key: Use IDE style when logging to stderr. */ static char log_stderr_ide[] = { "/log/stderr/ide" }; /** Preference key: Log file name. */ static char log_file_name[] = { "/log/file/name" }; /** Preference key: Log level for writing to file. */ static char log_file_level[] = { "/log/file/level" }; /** Preference key: Keep log file when exiting. */ static char log_file_keep[] = { "/log/file/keep" }; /** Preference key: Write timestamps when logging to file. */ static char log_file_time[] = { "/log/file/time" }; /** Preference key: Timestamps in logfile on separate lines. */ static char log_file_split[] = { "/log/file/split" }; /** Preference key: Log level for writing to stdout. */ static char log_stdout_level[] = { "/log/stdout/level" }; /** Preference key: Write timestamps when logging to stdout. */ static char log_stdout_time[] = { "/log/stdout/time" }; /** Preference key: Timestamps on stdout on separate lines. */ static char log_stdout_split[] = { "/log/stdout/split" }; /** Preference key: Log level for writing to stderr. */ static char log_stderr_level[] = { "/log/stderr/level" }; /** Preference key: Write timestamps when logging to stderr. */ static char log_stderr_time[] = { "/log/stderr/time" }; /** Preference key: Timestamps on stderr on separate lines. */ static char log_stderr_split[] = { "/log/stderr/split" }; /** Preference key: Syslog level. */ static char log_syslog_level[] = { "/log/syslog/level" }; #if DK_HAVE_CODEPAGES /** Preference key: Codepage for logging to file. */ static char log_file_codepage[] = { "/log/file/codepage" }; /** Preference key: Codepage for logging to stdout. */ static char log_stdout_codepage[] = { "/log/stdout/codepage" }; /** Preference key: Codepage for logging to stderr. */ static char log_stderr_codepage[] = { "/log/stderr/codepage" }; #endif /** Preference key: Application specific directory. */ static char app_dir[] = { "/dir/app" }; /** Preference key: Shared directory. */ static char shared_dir[] = { "/dir/shared" }; /** Preference key: Base directory for temporary directories. */ static char tmp_dir[] = { "/dir/tmp" }; /** Preference key: Keep temporary directory when exiting. */ static char key_keep_temp[] = { "/dir/tmp/keep" }; /** Preference key: Language/region/encoding. */ static char ui_lang[] = { "/ui/lang" }; /** Preference key: LANG environment variable overwrite preference value for language/region/encoding. */ static char ui_lang_env[] = { "/ui/lang/env" }; /** Preference key: Use trees for sorted storage. */ static char storage_trees[] = { "/storage/trees" }; /** Default language/region/encoding. */ static char default_language[] = { "en_US" }; #if DK_HAVE_CODEPAGES /** Minus sign, used when reading a codepage. */ static char minus_sign[] = { "-" }; #endif /** Get language/region/encoding settins. @param a Application. @param str A copy of the LANG environment variable, do not use the result of getenv("LANG") directly. The \a str string is modified! */ static void save_lang DK_P2(dk_app_t *, a, char *, str) { char *cptr; $? "+ save_lang" cptr = dkstr_chr(str, '.'); (a->loc).es = DK_APP_ENCODING_DEFAULT; if(cptr) { *(cptr++) = '\0'; if(strlen(cptr) > 0) { if((dkstr_casecmp(cptr, str_utf8_a) == 0) || (dkstr_casecmp(cptr, str_utf8_b) == 0)) { (a->loc).es = DK_APP_ENCODING_UTF8; (a->loc).e = dkstr_dup(str_utf8_a); } else { (a->loc).e = dkstr_dup(cptr); } } } cptr = dkstr_chr(str, '_'); if(cptr) { *(cptr++) = '\0'; if(strlen(cptr) > 0) { (a->loc).r = dkstr_dup(cptr); } } if(strlen(str) > 0) { (a->loc).l = dkstr_dup(str); } $? "- save_lang" } /** File open mode: Read binary. */ static char rb[] = { "rb" }; /** Check whether or not a file is a regular file. @param fn File name. @return 1 on success, 0 on error. */ static int file_check DK_P1(char *,fn) { int back = 0; dk_stat_t st; if(dkstat_get(&st,fn)) { if(((st.filetype) & (~(DK_FT_SYMLINK))) == DK_FT_REG) { back = 1; } } $? "= file_check %s %d", TR_STR(fn), back return back; } /** Debug message texts. */ static char *debug_strings[42]; /** String finder data for debug message texts. */ static dk_string_finder_t debug_string_finder[] = { { (char *)"/d/00", &(debug_strings[0]), (char *)"Login name: " }, { (char *)"/d/01", &(debug_strings[1]), (char *)"Application: " }, { (char *)"/d/02", &(debug_strings[2]), (char *)"Host name: " }, { (char *)"/d/03", &(debug_strings[3]), (char *)"HOME dir: " }, { (char *)"/d/04", &(debug_strings[4]), (char *)"TEMP dir: " }, { (char *)"/d/05", &(debug_strings[5]), (char *)"Application dir: " }, { (char *)"/d/06", &(debug_strings[6]), (char *)"Shared dir: " }, { (char *)"/d/07", &(debug_strings[7]), (char *)"Executable file: " }, { (char *)"/d/08", &(debug_strings[8]), (char *)"Executable dir: " }, { (char *)"/d/09", &(debug_strings[9]), (char *)"Log file: " }, { (char *)"/d/10", &(debug_strings[10]), (char *)"Language: " }, { (char *)"/d/11", &(debug_strings[11]), (char *)"Region: " }, { (char *)"/d/12", &(debug_strings[12]), (char *)"Encoding: " }, { (char *)"/d/13", &(debug_strings[13]), (char *)"unknown" }, { (char *)"/d/14", &(debug_strings[14]), (char *)"Proc temp dir: " }, { (char *)"/d/15", &(debug_strings[15]), (char *)"Checking file \"" }, { (char *)"/d/16", &(debug_strings[16]), (char *)"\"." }, { (char *)"/d/17", &(debug_strings[17]), (char *)"File \"" }, { (char *)"/d/18", &(debug_strings[18]), (char *)"\" found." }, { (char *)"/d/19", &(debug_strings[19]), (char *)"Program group: " }, { (char *)"/d/20", &(debug_strings[20]), (char *)"System conf dir: " }, { (char *)"/d/21", &(debug_strings[21]), (char *)"Attempt to seed OpenSSL PRNG." }, { (char *)"/d/22", &(debug_strings[22]), (char *)"Attempt to seed random() PRNG." }, { (char *)"/d/23", &(debug_strings[23]), (char *)"Attempt to seed rand48() PRNG." }, { (char *)"/d/24", &(debug_strings[24]), (char *)"Attempt to seed rand() PRNG." }, { (char *)"/d/25", &(debug_strings[25]), (char *)"Failed to seed OpenSSL PRNG!" }, { (char *)"/d/26", &(debug_strings[26]), (char *)"Failed to seed random() PRNG!" }, { (char *)"/d/27", &(debug_strings[27]), (char *)"Failed to seed rand48() PRNG!" }, { (char *)"/d/28", &(debug_strings[28]), (char *)"Failed to seed rand() PRNG!" }, { (char *)"/d/29", &(debug_strings[29]), (char *)"OpenSSL PRNG not available!" }, { (char *)"/d/30", &(debug_strings[30]), (char *)"random() PRNG not available!" }, { (char *)"/d/31", &(debug_strings[31]), (char *)"rand48() PRNG not available!" }, { (char *)"/d/32", &(debug_strings[32]), (char *)"rand() PRNG not available!" }, { (char *)"/d/33", &(debug_strings[33]), (char *)"Attempt to seed from file \"" }, { (char *)"/d/34", &(debug_strings[34]), (char *)"\"." }, { (char *)"/d/35", &(debug_strings[35]), (char *)"Attempt to seed from EGD socket \"" }, { (char *)"/d/36", &(debug_strings[36]), (char *)"\"." }, { (char *)"/d/37", &(debug_strings[37]), (char *)"Attempt to seed from device \"" }, { (char *)"/d/38", &(debug_strings[38]), (char *)"\"." }, { (char *)"/d/39", &(debug_strings[39]), (char *)"Attempt to seed from keyboard." }, { (char *)"/d/40", &(debug_strings[40]), (char *)"Attempt to seed from screen." }, { (char *)"/d/41", &(debug_strings[41]), (char *)"PRNG seeded successfully." }, {NULL, NULL, NULL} }; /** Message textes. */ static char *open_and_close_strings[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /** String finder data for message texts. */ static dk_string_finder_t open_and_close_finder[] = { { (char *)"/msg/01", &(open_and_close_strings[0]), (char *)"Application \"" }, { (char *)"/msg/02", &(open_and_close_strings[1]), (char *)"\" started." }, { (char *)"/msg/03", &(open_and_close_strings[2]), (char *)"Application \"" }, { (char *)"/msg/04", &(open_and_close_strings[3]), (char *)"\" finished." }, { (char *)"/msg/05", &(open_and_close_strings[4]), (char *)"File \"" }, { (char *)"/msg/06", &(open_and_close_strings[5]), (char *)"\" found." }, { (char *)"/msg/07", &(open_and_close_strings[6]), (char *)"File \"" }, { (char *)"/msg/08", &(open_and_close_strings[7]), (char *)"\" not found!." }, { (char *)"/msg/09", &(open_and_close_strings[8]), (char *)"File \"" }, { (char *)"/msg/10", &(open_and_close_strings[9]), (char *)"\" opened." }, { (char *)"/msg/11", &(open_and_close_strings[10]), (char *)"Failed to read \"" }, { (char *)"/msg/12", &(open_and_close_strings[11]), (char *)"\"!" }, { (char *)"/msg/13", &(open_and_close_strings[12]), (char *)"String table \"" }, { (char *)"/msg/14", &(open_and_close_strings[13]), (char *)"\" not found!." }, { (char *)"/msg/15", &(open_and_close_strings[14]), (char *)"String table \"" }, { (char *)"/msg/16", &(open_and_close_strings[15]), (char *)"\" found." }, { (char *)"/msg/17", &(open_and_close_strings[16]), (char *)"Different owners for symlink \""}, { (char *)"/msg/18", &(open_and_close_strings[17]), (char *)"\" and target file!" }, { (char *)"/msg/19", &(open_and_close_strings[18]), (char *)"Symlink \"" }, { (char *)"/msg/20", &(open_and_close_strings[19]), (char *)"\" resides in a group writable directory!" }, { (char *)"/msg/21", &(open_and_close_strings[20]), (char *)"Symlink \"" }, { (char *)"/msg/22", &(open_and_close_strings[21]), (char *)"\" resides in a world writable directory!" }, { (char *)"/msg/23", &(open_and_close_strings[22]), (char *)"No file name like \"" }, { (char *)"/msg/24", &(open_and_close_strings[23]), (char *)"\"!" }, { (char *)"/msg/25", &(open_and_close_strings[24]), (char *)"Too many file names for \"" }, { (char *)"/msg/26", &(open_and_close_strings[25]), (char *)"\"!" }, { (char *)"/msg/27", &(open_and_close_strings[26]), (char *)"\"" }, { (char *)"/msg/28", &(open_and_close_strings[27]), (char *)"\" is a directory!" }, { (char *)"/msg/29", &(open_and_close_strings[28]), (char *)"The temporary directory \"" }, { (char *)"/msg/30", &(open_and_close_strings[29]), (char *)"\" will not be deleted!" }, { (char *)"/msg/31", &(open_and_close_strings[30]), (char *)"Dynamic memory usage: " }, { (char *)"/msg/32", &(open_and_close_strings[31]), (char *)" bytes." }, { NULL, NULL, NULL } }; /** Flag: Error messages texts were searched. */ static int app_err_conf = 0; /** Error message texts. */ static char *app_err_str[42]; /** String finder data for error messages. */ static dk_string_finder_t app_err_find[] = { { (char *)"/e/00", &(app_err_str[0]), (char *)"Cannot traverse directory \"" }, { (char *)"/e/01", &(app_err_str[1]), (char *)"\"!" }, { (char *)"/e/02", &(app_err_str[2]), (char *)"No information about \"" }, { (char *)"/e/03", &(app_err_str[3]), (char *)"\"!" }, { (char *)"/e/04", &(app_err_str[4]), (char *)"Failed to estimate current working directory!" }, { (char *)"/e/05", &(app_err_str[5]), (char *)"Not enough memory! Failed to allocate " }, { (char *)"/e/06", &(app_err_str[6]), (char *)" elements, " }, { (char *)"/e/07", &(app_err_str[7]), (char *)" bytes per element." }, { (char *)"/e/08", &(app_err_str[8]), (char *)"No file matching \"" }, { (char *)"/e/09", &(app_err_str[9]), (char *)"\"!" }, { (char *)"/e/10", &(app_err_str[10]), (char *)"No directory matching \"" }, { (char *)"/e/11", &(app_err_str[11]), (char *)"\"!" }, { (char *)"/e/12", &(app_err_str[12]), (char *)"Failed to open file \"" }, { (char *)"/e/13", &(app_err_str[13]), (char *)"\" for read access!" }, { (char *)"/e/14", &(app_err_str[14]), (char *)"Failed to open file \"" }, { (char *)"/e/15", &(app_err_str[15]), (char *)"\" for write access!" }, { (char *)"/e/16", &(app_err_str[16]), (char *)"Error while writing to file \"" }, { (char *)"/e/17", &(app_err_str[17]), (char *)"\"!" }, { (char *)"/e/18", &(app_err_str[18]), (char *)"Error while reading from file \"" }, { (char *)"/e/19", &(app_err_str[19]), (char *)"\"!" }, { (char *)"/e/20", &(app_err_str[20]), (char *)"TCP/IP not available!" }, { (char *)"/e/21", &(app_err_str[21]), (char *)"Failed to open \"" }, { (char *)"/e/22", &(app_err_str[22]), (char *)"\"! No zlib support available." }, { (char *)"/e/23", &(app_err_str[23]), (char *)"\"! No bzip2 support available." }, { (char *)"/e/24", &(app_err_str[24]), (char *)"File \"" }, { (char *)"/e/25", &(app_err_str[25]), (char *)"\" is not a regular file!" }, { (char *)"/e/26", &(app_err_str[26]), (char *)"File \"" }, { (char *)"/e/27", &(app_err_str[27]), (char *)"\" does not exist!" }, { (char *)"/e/28", &(app_err_str[28]), (char *)"Invalid permissions on file \"" }, { (char *)"/e/29", &(app_err_str[29]), (char *)"\"!" }, { (char *)"/e/30", &(app_err_str[30]), (char *)"Invalid owner for file \"" }, { (char *)"/e/31", &(app_err_str[31]), (char *)"\"!" }, { (char *)"/e/32", &(app_err_str[32]), (char *)"\"" }, { (char *)"/e/33", &(app_err_str[33]), (char *)"\" is not a device!" }, { (char *)"/e/34", &(app_err_str[34]), (char *)"OpenSSL support is not available!" }, { (char *)"/e/35", &(app_err_str[35]), (char *)"PRNG should not be used for cryptographic purposes\nand/or user authentication!" }, { (char *)"/e/36", &(app_err_str[36]), (char *)"No PRNG available at all!\nThe requested PRNGs are either not available or cannot be seeded." }, { (char *)"/e/37", &(app_err_str[37]), (char *)"Some random keyboard input is needed to seed the PRNG.\nPlease hit some keys, press to finish: " }, { (char *)"/e/38", &(app_err_str[38]), (char *)"Some more random keyboard input is needed: " }, { (char *)"/e/39", &(app_err_str[39]), (char *)"Warning: Keyboard echo is *not* turned off!" }, { (char *)"/e/40", &(app_err_str[40]), (char *)"PRNG \"" }, { (char *)"/e/41", &(app_err_str[41]), (char *)"\" does not exist!" }, { NULL, NULL, NULL } }; void dkapp_err_memory DK_P3(dk_app_t *, app, size_t, elsize, size_t, nelem) { char *logmsg[5]; char buffer1[32], buffer2[32]; if(app) { sprintf(buffer1, "%lu", (unsigned long)nelem); sprintf(buffer2, "%lu", (unsigned long)elsize); logmsg[0] = app_err_str[5]; logmsg[1] = buffer1; logmsg[2] = app_err_str[6]; logmsg[3] = buffer2; logmsg[4] = app_err_str[7]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 5); } } void dkapp_err_nowrite DK_P3(dk_app_t *,app,char *,filename,int,reason) { char *logmsg[3]; if(app && filename) { switch(reason) { case DK_SF_SEC_WG : { logmsg[0] = open_and_close_strings[18]; logmsg[1] = filename; logmsg[2] = open_and_close_strings[19]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } break; case DK_SF_SEC_WO : { logmsg[0] = open_and_close_strings[20]; logmsg[1] = filename; logmsg[2] = open_and_close_strings[21]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } break; case DK_SF_SEC_OWNER : { logmsg[0] = open_and_close_strings[16]; logmsg[1] = filename; logmsg[2] = open_and_close_strings[17]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } break; case DK_SF_SEC_DIR: { logmsg[0] = open_and_close_strings[26]; logmsg[1] = filename; logmsg[2] = open_and_close_strings[27]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } break; } } } /** Data structure used to search for a file. */ typedef struct { size_t mpl; /**< Maximum path length. */ char *d1; /**< Buffer for directory to search for. */ char *d2; /**< Buffer for GetWindowsDirectory. */ char *d3; /**< Buffer for entire directory. */ int logenab; /**< Logging enabled. */ dk_app_t *a; /**< The application. */ char *buffer; /**< Destination buffer. */ size_t sz; /**< Destination buffer size. */ char *name; /**< Name of file to search for. */ int index_found; /**< -1: not found, 0: plain file, >0: use openstream */ dk_stream_suffix_t *sl; /**< Suffix list. */ int useunsecdir; /**< Use or not current directory. */ } file_finder_t; /** Initialize file finder. @param ff File finder to initialize. */ static void init_file_finder DK_P1(file_finder_t *,ff) { ff->mpl = 0; ff->d1 = ff->d2 = ff->d3 = NULL; ff->logenab = 0; ff->a = NULL; ff->buffer = NULL; ff->sz = 0; ff->index_found = -1; ff->sl = NULL; ff->name = NULL; ff->useunsecdir = 1; $? "= init_file_finder %s", TR_PTR(ff) } /** Open new file finder. @return Pointer to new file finder on success, NULL on error. */ static file_finder_t * new_file_finder DK_P0() { file_finder_t *back = NULL; char *d1, *d2, *d3; long l; size_t s; $? "+ new_file_finder" back = dk_new(file_finder_t,1); if(back) { init_file_finder(back); l = dksf_get_maxpathlen(); if(l <= 0L) l = 1024L; s = (size_t)l; back ->mpl = s; d1 = dk_new(char,s); d2 = dk_new(char,s); d3 = dk_new(char,s); if(d1 && d2 && d3) { back->d1 = d1; back->d2 = d2; back->d3 = d3; } else { if(d1) { dk_delete(d1); } if(d2) { dk_delete(d2); } if(d3) { dk_delete(d3); } dk_delete(back); back = NULL; } } $? "- new_file_finder %s", TR_PTR(back) return back; } /** Release file finder. @param ff File finder to release. */ static void delete_file_finder DK_P1(file_finder_t *,ff) { char *x; $? "+ delete_file_finder %s", TR_PTR(ff) if(ff) { x = ff->d1; if(x) { dk_delete(x); } x = ff->d2; if(x) { dk_delete(x); } x = ff->d3; if(x) { dk_delete(x); } ff->mpl = 0; ff->d1 = ff->d2 = NULL; ff->logenab = 0; ff->a = NULL; dk_delete(ff); } $? "- delete_file_finder" } /** Create debug messages for file search. @param a Application. @param fn File name. @param logenab Flag: Logging enabled. @return 1 on success, 0 on error. */ static int logged_file_check DK_P3(dk_app_t *,a,char *,fn,int,logenab) { int back = 0; char *logmsg[3]; if(fn) { if(a && logenab) { logmsg[0] = debug_strings[15]; logmsg[1] = fn; logmsg[2] = debug_strings[16]; dkapp_log_msg(a,DK_LOG_LEVEL_DEBUG,logmsg,3); } back = file_check(fn); if(a && logenab && back) { logmsg[0] = debug_strings[17]; logmsg[1] = fn; logmsg[2] = debug_strings[18]; dkapp_log_msg(a,DK_LOG_LEVEL_DEBUG,logmsg,3); } } return back; } /** Search for file. Check in one directory for filename, filename,gz and filename,bz2 @param ff File finder. @param usedir Combination of DK_APP_PNC_REGION, DK_APP_PNC_LANGUAGE and DK_APP_PNC_ENCODING. */ static void ff_dir DK_P2(file_finder_t *,ff,int,usedir) { size_t lgt; int lfd; dk_stream_suffix_t *sptr; $? "+ ff_dir %s %d", TR_PTR(ff), usedir lgt = strlen(ff->name); if(usedir) { lgt += (strlen(ff->d3) + strlen(fn_sep)); } if(lgt < ff->sz) { if(usedir) { strcpy(ff->buffer, ff->d3); strcat(ff->buffer, fn_sep); strcat(ff->buffer, ff->name); } else { strcpy(ff->buffer, ff->name); } dksf_correct_fnsep(ff->buffer); if(logged_file_check(ff->a,ff->buffer,ff->logenab)) { ff->index_found = 0; } } if((ff->index_found) == -1) { if(ff->sl) { sptr = ff->sl; lfd = 1; while((sptr->suffix) && ((ff->index_found) == -1)) { lgt = strlen(ff->name) + strlen(sptr->suffix); if(usedir) { lgt += (strlen(ff->d3) + strlen(fn_sep)); } if(lgt < ff->sz) { if(usedir) { strcpy(ff->buffer, ff->d3); strcat(ff->buffer, fn_sep); strcat(ff->buffer, ff->name); } else { strcpy(ff->buffer, ff->name); } strcat(ff->buffer, sptr->suffix); dksf_correct_fnsep(ff->buffer); if(logged_file_check(ff->a,ff->buffer,ff->logenab)) { ff->index_found = lfd; } } sptr++; lfd++; } } } $? "- ff_dir %d", ff->index_found } /** Search in subdirectories for a file. Check for filename, filename.gz and filename.bz2 in the language, region and encoding subdirectories. @param ff File finder. @param subdir Pointer to variable containing a combination of DK_APP_PNC_REGION, DK_APP_PNC_LANGUAGE and DK_APP_PNC_ENCODING. */ static void ff_subs DK_P2(file_finder_t *,ff, int *,subdir) { int i1, do_the_check; size_t lgt; $? "+ ff_subs" i1 = 8; while((i1 > 0) && ((ff->index_found) == -1)) { i1--; do_the_check = 1; lgt = strlen(ff->d1); if(i1 & DK_APP_PNC_LANGUAGE) { if(((ff->a)->loc).l) { lgt++; lgt += strlen(((ff->a)->loc).l); } else { do_the_check = 0; } } if(i1 & DK_APP_PNC_REGION) { if(((ff->a)->loc).r) { lgt++; lgt += strlen(((ff->a)->loc).r); } else { do_the_check = 0; } } if(i1 & DK_APP_PNC_ENCODING) { if(((ff->a)->loc).e) { lgt++; lgt += strlen(((ff->a)->loc).e); } else { do_the_check = 0; } } if(do_the_check) { if(lgt < ff->mpl) { strcpy(ff->d3, ff->d1); if(i1 & DK_APP_PNC_LANGUAGE) { strcat(ff->d3, fn_sep); strcat(ff->d3, ((ff->a)->loc).l); } if(i1 & DK_APP_PNC_REGION) { strcat(ff->d3, fn_sep); strcat(ff->d3, ((ff->a)->loc).r); } if(i1 & DK_APP_PNC_ENCODING) { strcat(ff->d3, fn_sep); strcat(ff->d3, ((ff->a)->loc).e); } ff_dir(ff, 1); } } if(ff->index_found != -1) { if(*subdir) { *subdir = i1; } } } $? "- ff_subs" } /** Run file search. @param ff File finder. @param subdir Pointer to variable containing a combination of DK_APP_PNC_REGION, DK_APP_PNC_LANGUAGE and DK_APP_PNC_ENCODING. */ static void ff_run DK_P2(file_finder_t *,ff, int *,subdir) { int i1; char *my_sysconfdir; $? "+ ff_run" /* nothing found yet */ my_sysconfdir = unix_sysconfdir; if(ff->a) { if(((ff->a)->d).etc) { my_sysconfdir = ((ff->a)->d).etc; } } ff->index_found = -1; i1 = 12; while((i1 > 0) && ((ff->index_found) == -1)) { switch(i1) { case 12: { /* current directory */ if(ff->useunsecdir) { ff_dir(ff, 0); } } break; case 11: { /* home directory */ if(ff->useunsecdir) { if(ff->a) { if(((ff->a)->d).h) { if(strlen(((ff->a)->d).h) < ff->mpl) { strcpy(ff->d3, ((ff->a)->d).h); ff_dir(ff,1); } } } } } break; case 10: { /* home/.defaults */ if(ff->useunsecdir) { if(ff->a) { if(((ff->a)->d).h) { if((strlen(((ff->a)->d).h)+strlen(fn_sep) +strlen(defaults_sub)) < ff->mpl) { strcpy(ff->d3, ((ff->a)->d).h); strcat(ff->d3, fn_sep); strcat(ff->d3, defaults_sub); ff_dir(ff,1); } } } } } break; case 9: { if(ff->useunsecdir) { if(((ff->a)->d).a) { if(strlen(((ff->a)->d).a) < ff->mpl) { strcpy(ff->d1, ((ff->a)->d).a); ff_subs(ff, subdir); } } } } break; case 8: { if(ff->useunsecdir) { if((((ff->a)->d).s) && (((ff->a)->n).g)) { if((1+strlen(((ff->a)->d).s) + strlen(((ff->a)->n).g)) < ff->mpl) { strcpy(ff->d1, ((ff->a)->d).s); strcat(ff->d1, fn_sep); strcat(ff->d1, ((ff->a)->n).g); ff_subs(ff, subdir); } } } } break; case 7: { if(ff->useunsecdir) { if(((ff->a)->d).s) { if(strlen(((ff->a)->d).s) < ff->mpl) { strcpy(ff->d1, ((ff->a)->d).s); ff_subs(ff, subdir); } } } } break; case 6: { #if DK_HAVE_GETWINDOWSDIRECTORY UINT uSize; $? ". DK_HAVE_GETWINDOWSDIRECTORY" uSize = GetWindowsDirectoryA((LPTSTR)(ff->d2), (UINT)(ff->mpl)); if((uSize > 0) && (uSize < ((UINT)(ff->mpl)))) { $? ". if((uSize > 0) && (uSize < ((UINT)(ff->mpl))))" if(((ff->a)->n).a) { $? ". if(((ff->a)->n).a)" if((1 + strlen(ff->d2) + strlen(((ff->a)->n).a)) < ff->mpl) { $? ". if((1 + strlen(ff->d2) + strlen(((ff->a)->n).a)) < ff->mpl)" strcpy(ff->d1, ff->d2); strcat(ff->d1, fn_sep); strcat(ff->d1, ((ff->a)->n).a); ff_subs(ff, subdir); } else { $? "! if((1 + strlen(ff->d2) + strlen(((ff->a)->n).a)) < ff->mpl)" } } else { $? "! if(((ff->a)->n).a)" } } else { i1 = 4; if(uSize == 0) { $? "! GetLastError() = %lu", (unsigned long)GetLastError() } $? "! if((uSize > 0) && (uSize < ((UINT)(ff->mpl))))" } #else i1 = 4; $? "! DK_HAVE_GETWINDOWSDIRECTORY" #endif } break; case 5: { #if DK_HAVE_GETWINDOWSDIRECTORY if(((ff->a)->n).g) { if((1 + strlen(ff->d2) + strlen(((ff->a)->n).g)) < ff->mpl) { strcpy(ff->d1, ff->d2); strcat(ff->d1, fn_sep); strcat(ff->d1, ((ff->a)->n).g); ff_subs(ff, subdir); } } #else i1 = 4; #endif } break; case 4: { #if DK_HAVE_GETWINDOWSDIRECTORY if(strlen(ff->d2) < ff->mpl) { strcpy(ff->d1, ff->d2); ff_subs(ff, subdir); } #endif } break; case 3: { if(((ff->a)->n).a) { if((1 + strlen(my_sysconfdir) + strlen(((ff->a)->n).a)) < ff->mpl) { strcpy(ff->d1, my_sysconfdir); strcat(ff->d1, fn_sep); strcat(ff->d1, ((ff->a)->n).a); ff_subs(ff, subdir); } } } break; case 2: { if(((ff->a)->n).g) { if((1 + strlen(my_sysconfdir) + strlen(((ff->a)->n).g)) < ff->mpl) { strcpy(ff->d1, my_sysconfdir); strcat(ff->d1, fn_sep); strcat(ff->d1, ((ff->a)->n).g); ff_subs(ff, subdir); } } } break; case 1: { if(strlen(my_sysconfdir) < ff->mpl) { strcpy(ff->d1, my_sysconfdir); ff_subs(ff, subdir); } } break; } i1--; } if(ff->logenab) { char *errmsgs[3]; if((ff->index_found) == -1) { errmsgs[0] = open_and_close_strings[6]; errmsgs[1] = ff->name; errmsgs[2] = open_and_close_strings[7]; dkapp_log_msg(ff->a,DK_LOG_LEVEL_ERROR,errmsgs,3); } else { errmsgs[0] = open_and_close_strings[4]; errmsgs[1] = ff->buffer; errmsgs[2] = open_and_close_strings[5]; dkapp_log_msg(ff->a,DK_LOG_LEVEL_PROGRESS,errmsgs,3); } } $? "- ff_run %d", ff->index_found } /** Open file for reading. @param a Application. @param name File name. @param logenab Flag: Logging enabled. @param useunsecdir Flag: Use user-writable directories. @param subdir Combination of DK_APP_PNC_LANGUAGE, DK_APP_PNC_REGION, DK_APP_PNC_ENCODING. @return Stream to read the file, must be closed using dkstream_close(). */ static dk_stream_t * my_read_file_ext1 DK_P5(dk_app_t *,a,char *,name,int,logenab,int,useunsecdir, int *,subdir) { dk_stream_t *back = NULL; file_finder_t *ff; dk_stream_suffix_t *sl; dk_stream_open_fct_t *fct; char *fnb; $? "+ my_read_file_ext1 %s %s %d", TR_PTR(a), TR_STR(name), logenab if(a && name) { ff = new_file_finder(); if(ff) { fnb = dk_new(char,(ff->mpl)); if(fnb) { ff->logenab = logenab; ff->a = a; ff->buffer = fnb; ff->sz = ff->mpl; ff->name = name; ff->useunsecdir = useunsecdir; sl = ff->sl = dkstream_get_read_suffixes(); ff_run(ff, subdir); if((ff->index_found) > -1) { if((ff->index_found) > 0) { fct = sl[((ff->index_found) - 1)].fct; if(fct) { a->relaxed_fopen_reason = 0; back = ((*fct)(fnb,rb,a->relaxed_fopen_check, &(a->relaxed_fopen_reason))); if(logenab) { if(back) { char *errmsgs[3]; errmsgs[0] = open_and_close_strings[8]; errmsgs[1] = ff->buffer; errmsgs[2] = open_and_close_strings[9]; dkapp_log_msg(a,DK_LOG_LEVEL_PROGRESS,errmsgs,3); } else { if(a->relaxed_fopen_reason) { dkapp_err_nowrite(a, fnb, a->relaxed_fopen_reason); } else { char *errmsgs[3]; errmsgs[0] = open_and_close_strings[10]; errmsgs[1] = ff->buffer; errmsgs[2] = open_and_close_strings[11]; dkapp_log_msg(a,DK_LOG_LEVEL_ERROR,errmsgs,3); } } } } } else { back = dkapp_stream_openfile(a, fnb, rb); if(logenab) { if(back) { char *errmsgs[3]; errmsgs[0] = open_and_close_strings[8]; errmsgs[1] = ff->buffer; errmsgs[2] = open_and_close_strings[9]; dkapp_log_msg(a,DK_LOG_LEVEL_PROGRESS,errmsgs,3); } else { char *errmsgs[3]; errmsgs[0] = open_and_close_strings[10]; errmsgs[1] = ff->buffer; errmsgs[2] = open_and_close_strings[11]; dkapp_log_msg(a,DK_LOG_LEVEL_ERROR,errmsgs,3); } } } } dk_delete(fnb); } else { dkapp_err_memory(a,sizeof(char),(ff->mpl)); } delete_file_finder(ff); } else { dkapp_err_memory(a,sizeof(file_finder_t),1); } } $? "- my_read_file_ext1 %s", TR_PTR(back) return back; } /** Open a file for reading. @param a Application. @param name File name. @param logenab Flag: Logging enabled. @param useunsecdir Use user-writable directories. @return Stream to read the file, must be closed using dkstream_close(). */ static dk_stream_t * my_read_file DK_P4(dk_app_t *,a,char *,name,int,logenab,int,useunsecdir) { dk_stream_t *back = NULL; int subdir; subdir = 0; back = my_read_file_ext1(a, name, logenab, useunsecdir, &subdir); return back; } /** Find file. @param a Application. @param name File name (without directory). @param buffer Result buffer. @param sz Size of \a buffer. @param uud Flag: Use user-writable directories. @param subdirtype Combination of DK_APP_PNC_LANGUAGE, DK_APP_PNC_REGION, DK_APP_PNC_ENCODING. @return 1 on success, 0 on error. */ static int int_find_file_ext1 DK_P6(dk_app_t *,a,char *,name,char *,buffer,size_t,sz,int,uud,int *,subdirtype) { int back = 0; file_finder_t *ff; $? "+ int_find_file %s %s %s %lu %d", TR_PTR(a), TR_STR(name), TR_PTR(buffer), (unsigned long)sz, uud if(a && name && buffer && sz) { ff = new_file_finder(); if(ff) { ff->logenab = 1; ff->a = a; ff->buffer = buffer; ff->sz = sz; ff->name = name; ff->sl = NULL; ff->useunsecdir = uud; ff_run(ff, subdirtype); if((ff->index_found) > -1) { back = 1; } delete_file_finder(ff); } else { dkapp_err_memory(a,sizeof(file_finder_t),1); } } $? "- int_find_file %d", back return back; } /** Find file. @param a Application. @param name File name (without directory). @param buffer Result buffer. @param sz Size of \a buffer. @param uud Flag: Use user-writable directories @return 1 on success, 0 on error. */ static int int_find_file DK_P5(dk_app_t *,a,char *,name,char *,buffer,size_t,sz,int,uud) { int back = 0; int i = 0; back = int_find_file_ext1(a,name,buffer,sz,uud,&i); return back; } /** Find file, create a new file name string. Note: On success the function allocates memory for the new string. You must release the memory using dk_delete(). @param a Application. @param n File name (without directory). @param uud Use user-writable directories. @param subdirtype @return A new string containing the full path name. */ static char * int_find_file_dup_ext1 DK_P4(dk_app_t *,a,char *,n,int,uud,int *,subdirtype) { char *back = NULL; char *buffer = NULL; long l; size_t sz; if((a) && (n)) { l = dksf_get_maxpathlen(); sz = (size_t)l; buffer = dk_new(char,sz); if(buffer) { if(int_find_file_ext1(a,n,buffer,sz,uud,subdirtype)) { back = dkstr_dup(buffer); if(!back) { dkapp_err_memory(a,sizeof(char),(1+strlen(buffer))); } } dk_delete(buffer); buffer = NULL; } else { dkapp_err_memory(a,sizeof(char),sz); } } return back; } /** Find file, create a new file name string. Note: On success the function allocates memory for the new string. You must release the memory using dk_delete(). @param a Application. @param n File name (without directory). @param uud Flag: Use user-writable directories @return A new string containing the full path name. */ static char * int_find_file_dup DK_P3(dk_app_t *,a,char *,n,int,uud) { char *back = NULL; int i = 0; back = int_find_file_dup_ext1(a,n,uud,&i); return back; } char * dkapp_find_file_dup_ext1 DK_P3(dk_app_t *,a,char *,n,int *,subdirtype) { char *back = NULL; $? "+ dkapp_find_file_dup %s %s", TR_PTR(a), TR_STR(n) back = int_find_file_dup_ext1(a,n,1,subdirtype); $? "- dkapp_find_file_dup %s", TR_STR(back) return back; } char * dkapp_find_file_dup DK_P2(dk_app_t *,a,char *,n) { char *back = NULL; int i = 0; back = dkapp_find_file_dup_ext1(a,n,&i); return back; } int dkapp_find_file_ext1 DK_P5(dk_app_t *,a,char *,name,char *,buffer,size_t,sz, int *,subdirtype) { int back = 0; $? "+ dkapp_find_file %s %s %s %lu", TR_PTR(a), TR_STR(name), TR_PTR(buffer), (unsigned long)sz back = int_find_file_ext1(a,name,buffer,sz,1,subdirtype); $? "- dkapp_find_file %d", back return back; } int dkapp_find_file DK_P4(dk_app_t *,a,char *,name,char *,buffer,size_t,sz) { int back = 0; int i = 0; back = dkapp_find_file_ext1(a, name, buffer, sz, &i); return back; } char * dkapp_find_cfg_dup DK_P2(dk_app_t *,a,char *,n) { char *back = NULL; $? "+ dkapp_find_cfg_dup %s %s", TR_PTR(a), TR_STR(n) back = int_find_file_dup(a,n,0); $? "- dkapp_find_cfg_dup %s", TR_STR(back) return back; } int dkapp_find_cfg DK_P4(dk_app_t *,a,char *,name,char *,buffer,size_t,sz) { int back = 0; $? "+ dkapp_find_cfg %s %s %s %lu", TR_PTR(a), TR_STR(name), TR_PTR(buffer), (unsigned long)sz back = int_find_file(a,name,buffer,sz,0); $? "- dkapp_find_cfg %d", back return back; } dk_stream_t * dkapp_read_file_ext1 DK_P3(dk_app_t *, a, char *, filename, int *,subdirtype) { dk_stream_t *back = NULL; $? "+ dkapp_read_file %s %s", TR_PTR(a), TR_STR(filename) back = my_read_file_ext1(a,filename,1,1,subdirtype); $? "- dkapp_read_file %s", TR_PTR(back) return back; } dk_stream_t * dkapp_read_file DK_P2(dk_app_t *, a, char *, filename) { dk_stream_t *back = NULL; int i = 0; back = dkapp_read_file_ext1(a, filename, &i); return back; } dk_stream_t * dkapp_read_cfg DK_P2(dk_app_t *, a, char *, filename) { dk_stream_t *back = NULL; $? "+ dkapp_read_cfg %s %s", TR_PTR(a), TR_STR(filename) back = my_read_file(a,filename,1,0); $? "- dkapp_read_cfg %s", TR_PTR(back) return back; } /** File name sufix for string tables. */ static char suffix_stt[] = { ".stt" }; /** Find a string table. @param app Application. @param table String table name. @return String table object or NULL. */ static stt_entry * find_stt_entry DK_P2(dk_app_t *, app, char *, table) { stt_entry *stteptr = NULL; char *buffer, *cptr; long maxpathlen; dk_stream_t *strm; dk_stt_t *sttptr; int found; $? "+ find_stt_entry %s %s", TR_PTR(app), TR_STR(table) if(((app->loc).s) && ((app->loc).si)) { stteptr = (stt_entry *)dksto_it_find_like(((app->loc).si),((void *)table),1); if(!stteptr) { $? ". need to read string table" maxpathlen = dksf_get_maxpathlen(); if(maxpathlen < 0L) { maxpathlen = 1024L; } buffer = dk_new(char,maxpathlen); if(buffer) { $? ". filename buffer allocated" if((strlen(table) + 7) < (size_t)maxpathlen) { strcpy(buffer, table); found = 0; cptr = dksf_get_file_type_dot(buffer); if(cptr) { if(strcmp(cptr, suffix_stt) == 0) { found = 1; } } if(!found) { strcat(buffer, suffix_stt); } $? ". searching for file %s", buffer strm = my_read_file(app,buffer,0,1); if(strm) { $? ". file opened" sttptr = dkstt_open(strm); if(sttptr) { $? ". string table allocated" stteptr = dk_new(stt_entry,1); if(stteptr) { $? ". stt-entry allocated" stteptr->name = NULL; stteptr->st = NULL; stteptr->name = dkstr_dup(table); if(stteptr->name) { $? ". stt-entry name %s", stteptr->name stteptr->st = sttptr; $? ". string table noted in stteptr" if(!dksto_add(((app->loc).s),((void *)stteptr))) { $? "! failed to add stteptr to list" stt_entry_free(stteptr); stteptr = NULL; sttptr = NULL; } } else { stteptr->name = NULL; dk_delete(stteptr); stteptr = NULL; dkstt_close(sttptr); sttptr = NULL; } } else { dkstt_close(sttptr); sttptr = NULL; } } dkstream_close(strm); } } } if(buffer) { dk_delete(buffer) ; } } } $? "- find_stt_entry %s", TR_PTR(stteptr) return stteptr; } /** Priority names. */ static char *log_level_keywords[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /** String finder data for priority names. */ static dk_string_finder_t log_level_string_finder[] = { { (char *)"/ll/n" , (&(log_level_keywords[0])), (char *)"" }, { (char *)"/ll/pa" , (&(log_level_keywords[1])), (char *)"PANIC: " }, { (char *)"/ll/f" , (&(log_level_keywords[2])), (char *)"FATAL: " }, { (char *)"/ll/e" , (&(log_level_keywords[3])), (char *)"ERROR: " }, { (char *)"/ll/w" , (&(log_level_keywords[4])), (char *)"Warning: " }, { (char *)"/ll/i" , (&(log_level_keywords[5])), (char *)"" }, { (char *)"/ll/pr" , (&(log_level_keywords[6])), (char *)"" }, { (char *)"/ll/d" , (&(log_level_keywords[7])), (char *)"Debug: " }, { (char *)"/ll/ign", (&(log_level_keywords[8])), (char *)"" }, { NULL, NULL, NULL } } ; /** Get priority name. @param i Priority. @return Priority name or NULL. */ static char * get_prio_string DK_P1(int, i) { int x; char *back = NULL; x = i; if(x < 1) x = 1; if(x > 7) x = 7; back = log_level_keywords[x]; return back; } /** Keywords to output messages in an IDE style. */ static char *ide_output_words[] = { (char *)"line", (char *)"error", (char *)"warning", (char *)"C2000", (char *)"C4000", NULL }; /** Keywords for TASM-style output. */ static char *tasm_keywords[] = { (char *)"", (char *)"*Warning*", (char *)"**Error**", (char *)"**Fatal**", NULL }; /** Add log message to log file. @param f Output file. @param fl Flags: 1=print timestamp, 2=separate line @param ts Timestamp @param min Required priority for this destination. @param p Message priority. @param msg Text array. @param az Number of entries in \a msg. @param cp Codepage to use. @param ide_type IDE style to simulate. @param name Source file name. @param lineno Source file line number. @param timer Time of this message. @param time_last Previously printed time. */ static void file_log DK_P13(FILE *,f,int,fl,char *,ts,int,min,int,p,char **,msg,int,az,unsigned char *,cp,int,ide_type,char *,name,unsigned long,lineno, time_t *,timer, time_t*, time_last) { int i; char *x, *kw; $? "+ file_log %s %d %s %d %d %s %d %s", TR_PTR(f), fl, TR_STR(ts), min, p, TR_PTR(msg), az, TR_PTR(cp) if(f && (p <= min)) { $? ". log level ok" if(fl & 1) { if(fl & 2) { if(*timer != *time_last) { fputs("# ", f); fputs(ts, f); fputc('\n', f); *time_last = *timer; } } else { fputs(ts, f); fputc(' ', f); } } $? ". nach eventuellem Drucken des Datums / vor Ausgabe" if(ide_type && name && lineno) { switch(ide_type) { case DK_APP_IDE_TASM : { $? ". TASM style" kw = tasm_keywords[0]; if(p <= DK_LOG_LEVEL_WARNING) { kw = tasm_keywords[1]; if(p <= DK_LOG_LEVEL_ERROR) { kw = tasm_keywords[2]; if(p <= DK_LOG_LEVEL_FATAL) { kw = tasm_keywords[3]; } } } fprintf(f, "%s %s(%lu) ", kw, name, lineno); } break; case DK_APP_IDE_WORKSHOP : { $? ". Workshop style" if(p <= DK_LOG_LEVEL_ERROR) { fprintf(f, "\"%s\", %s %lu: ", name, ide_output_words[0], lineno ); } else { if(p == DK_LOG_LEVEL_WARNING) { fprintf(f, "\"%s\". %s %lu: %s: ", name, ide_output_words[0], lineno, ide_output_words[2] ); } } } break; case DK_APP_IDE_MSVC : { $? ". MSVC style" if(p <= DK_LOG_LEVEL_ERROR) { fprintf(f, "%s(%lu) : %s %s: ", name, lineno, ide_output_words[1], ide_output_words[3] ); } else { if(p == DK_LOG_LEVEL_WARNING) { fprintf(f, "%s(%lu) : %s %s: ", name, lineno, ide_output_words[2], ide_output_words[4] ); } } } break; default : { $? ". gcc style" if(p <= DK_LOG_LEVEL_ERROR) { fprintf(f, "%s:%lu: ", name, lineno ); } else { if(p == DK_LOG_LEVEL_WARNING) { fprintf(f, "%s:%lu: %s: ", name, lineno, ide_output_words[2] ); } else { fputs(name, f); fputs(": ", f); } } } break; } $? ". mit Quelltext-Angabe" } else { $? ". ohne Quelltext-Angabe" if(name) { if(lineno) { fprintf(f, "%s:%lu: ", name, lineno ); } else { fputs(name, f); fputs(": ", f); } } x = get_prio_string(p); $? ". get_prio_string(p) = %s", TR_STR(x) if(x) { fputs(x, f); } } $? ". eigentliche Ausgabe" #if DK_HAVE_CODEPAGES $? ". codepage support enabled" if(cp) { $? ". have codepage" for(i = 0; i < az; i++) { $? ". msg %d / %d", i, az if(msg[i]) { $? ". msg ok" dkcp_fputs(f, cp, msg[i]); $? ". dkcp_fputs ok" } } } else { #else $? ". codepage support disabled" #endif for(i = 0; i < az; i++) { $? ". msg %d / %d", i, az if(msg[i]) { $? ". msg ok" fputs(msg[i], f); } } #if DK_HAVE_CODEPAGES } #endif $? ". finishing line" fputc('\n', f); fflush(f); } $? "- file_log" } int dkapp_llmax_get DK_P1(dk_app_t *,a) { int back = DK_LOG_LEVEL_IGNORE; if(a) { back = (a->l).max; } return back; } void dkapp_llmax_set DK_P2(dk_app_t *,a, int,l) { if(a) { (a->l).max = l; if((a->l).max < DK_LOG_LEVEL_NONE) { (a->l).max = DK_LOG_LEVEL_NONE; } if((a->l).max > DK_LOG_LEVEL_IGNORE) { (a->l).max = DK_LOG_LEVEL_IGNORE; } } } int dkapp_log_msg DK_P4(dk_app_t *, a, int, p, char **, msg, int, az) { int back = 0; char time_buffer[32]; #if DK_HAVE_TIME_H static time_t time_last_stdout = (time_t)0; static time_t time_last_stderr = (time_t)0; static time_t time_last_file = (time_t)0; time_t timer; #endif #if DK_HAVE_SYSLOG size_t lgt; int i, xp; char *buffer, *ps; #endif $? "+ dkapp_log_msg %s %d %s %d", TR_PTR(a), p, TR_PTR(msg), az time_buffer[0] = '\0'; if(p < ((a->l).max)) { (a->l).max = p; } #if DK_HAVE_TIME_H time(&timer); dksf_time_convert(time_buffer,timer); #endif if(a && msg && (az > 0)) { $? ". arguments ok" back = 1; $? ". logging to stdout" if(!(((a->l).nostdio) & DK_APP_LOG_NO_STDOUT)) { file_log( stdout, ((a->l).o.f), time_buffer,((a->l).o.m), p,msg,az,((a->l).o.c), ((a->l).o.ide_type), ((a->l).ef.n), ((a->l).ef.lineno), &timer, &time_last_stdout ); } $? ". logging to stderr" if(!(((a->l).nostdio) & DK_APP_LOG_NO_STDERR)) { file_log( stderr,((a->l).e.f),time_buffer,((a->l).e.m), p,msg,az,((a->l).e.c), ((a->l).e.ide_type), ((a->l).ef.n), ((a->l).ef.lineno), &timer, &time_last_stderr ); } $? ". logging to file" file_log( ((a->l).f.t),((a->l).f.f),time_buffer,((a->l).f.m), p,msg,az,((a->l).f.c), ((a->l).e.ide_type), ((a->l).ef.n), ((a->l).ef.lineno), &timer, &time_last_file ); $? ". file logging done" #if DK_HAVE_SYSLOG $? ". syslog enabled" if(((a->l).s.o) && (p <= ((a->l).s.m))) { $? ". logging to syslog" ps = get_prio_string(p); lgt = strlen(ps); for(i = 0; i < az; i++) { if(msg[i]) { lgt += strlen(msg[i]); } } lgt++; buffer = dk_new(char,lgt); if(buffer) { strcpy(buffer, ps); for(i = 0; i < az; i++) { if(msg[i]) { strcat(buffer, msg[i]); } } xp = LOG_INFO; switch(p) { case DK_LOG_LEVEL_DEBUG: xp = LOG_DEBUG; break; case DK_LOG_LEVEL_PROGRESS: xp = LOG_DEBUG; break; case DK_LOG_LEVEL_INFO: xp = LOG_INFO; break; case DK_LOG_LEVEL_WARNING: xp = LOG_WARNING; break; case DK_LOG_LEVEL_ERROR: xp = LOG_ERR; break; case DK_LOG_LEVEL_FATAL: xp = LOG_CRIT; break; case DK_LOG_LEVEL_PANIC: xp = LOG_EMERG; break; } syslog(xp,"%s",buffer); dk_delete(buffer); } } #endif } $? "- dkapp_log_msg %d", back return back; } /** Macro names for replacements. */ static char *specials[] = { /* 0 */ (char *)"app.name", /* 1 */ (char *)"app.dir", /* 2 */ (char *)"shared.dir", /* 3 */ (char *)"temp.dir", /* 4 */ (char *)"user.name", /* 5 */ (char *)"user.home", /* 6 */ (char *)"user.uid", /* 7 */ (char *)"user.gid", /* 8 */ (char *)"user.euid", /* 9 */ (char *)"user.egid", /* 10 */ (char *)"host.name", /* 11 */ (char *)"host.domain", /* 12 */ (char *)"process.pid", /* 13 */ (char *)"process.ppid", /* 14 */ (char *)"process.pgid", NULL }; /** String: Information obtained from preferences. */ static char str_pref[] = { "pref:" }; /** String: Information obtained from environment. */ static char str_env[] = { "env:" }; /** String for unknown sources. */ static char str_unknown[] = { "x" }; /** Transform a macro. @param app Application. @param str In: macro to replace, out: replacement text. @param sz Size of the \a str buffer. @return 1 on success, 0 on error. */ static int transformSpecial DK_P3(dk_app_t *,app,char *,str,size_t,sz) { int back = 0; int i; char *xbuffer, *ptr; size_t lgt1, lgt2; long l; i = dkstr_array_index(specials, str, 0); if(i >= 0) { switch(i) { case 0: { $? "app name" if((app->n).a) { if(strlen((app->n).a) < sz) { strcpy(str, (app->n).a); back = 1; } } } break; case 1: { $? "app dir" if((app->d).a) { if(strlen((app->d).a) < sz) { strcpy(str, (app->d).a); back = 1; } } } break; case 2: { if((app->d).s) { if(strlen((app->d).s) < sz) { strcpy(str, (app->d).s); back = 1; } } } break; case 3: { if((app->d).t) { if(strlen((app->d).t) < sz) { strcpy(str, (app->d).t); back = 1; } } } break; case 4: { if((app->n).u) { if(strlen((app->n).u) < sz) { strcpy(str, (app->n).u); back = 1; } } } break; case 5: { if((app->d).h) { if(strlen((app->d).h) < sz) { strcpy(str, (app->d).h); back = 1; } } } break; case 6: { if(sz > 11) { back = 1; if(dksf_have_getuid()) { l = dksf_getuid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 7: { if(sz > 11) { back = 1; if(dksf_have_getgid()) { l = dksf_getgid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 8: { if(sz > 11) { back = 1; if(dksf_have_geteuid()) { l = dksf_geteuid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 9: { if(sz > 11) { back = 1; if(dksf_have_getegid()) { l = dksf_getegid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 10: { back = dksf_get_hostname(str,sz); } break; case 11: { back = dksf_get_domainname(str,sz); } break; case 12: { if(sz > 11) { back = 1; if(dksf_have_getpid()) { l = dksf_getpid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 13: { if(sz > 11) { back = 1; if(dksf_have_getppid()) { l = dksf_getppid(); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; case 14: { if(sz > 11) { back = 1; if(dksf_have_getpgid()) { l = dksf_getpgid(dksf_getpid()); sprintf(str, "%lu", (unsigned long)l); } else { strcpy(str, str_unknown); } } } break; } } else { lgt1 = strlen(str); lgt2 = strlen(str_env); if(lgt1 > lgt2) { if(strncmp(str,str_env,lgt2) == 0) { ptr = getenv(&(str[lgt2])); if(ptr) { if(strlen(ptr) < sz) { strcpy(str,ptr); back = 1; } } } if(!back) { lgt2 = strlen(str_pref); if(lgt1 > lgt2) { if(strncmp(str,str_pref,lgt2) == 0) { xbuffer = dk_new(char,sz); if(xbuffer) { strcpy(xbuffer,&(str[lgt2])); back = dkapp_get_pref(app,xbuffer,str,sz,0); dk_delete(xbuffer); } } } } } } return back; } /** flag: Use backslash in file names. */ #if DK_HAVE_FEATURE_BACKSLASH #define FNSBS 1 #else #define FNSBS 0 #endif /** Flag: File name parts are separated by backslashes. */ static int fnsbs = FNSBS; int dkapp_transform_string_ext1 DK_P5(dk_app_t *,app,char *,dest,size_t,sz,char *,src,int,fn) { int back = 1; char tmp[256]; char *dptr, *tptr, *sptr; size_t dsz, tsz; int state; $? "+ kAppTransformString" if(app && dest && src && sz) { $? ". src = %s", src dptr = dest; tptr = tmp; sptr = src; state = 0; dsz = tsz = 0; while(*sptr) { switch(state) { case 1: { $? ". nach $" switch(*sptr) { case '(': { tptr = tmp; tsz = 0; state = 2; } break; default: { if(dsz + 2 < sz) { *(dptr++) = '$'; *(dptr++) = *sptr; dsz++; dsz++; } else { back = 0; } state = 0; } break; } } break; case 2: { $? ". nach $(" switch(*sptr) { case ')': { $? ". transformSpecial noetig" *tptr = (char)0; $? ". -> transformSpecial %s", tmp if(transformSpecial(app, tmp, sizeof(tmp))) { $? ". <- transformSpecial %s", tmp if((dsz + strlen(tmp)) < sz) { tptr = tmp; while(*tptr) { *(dptr++) = *(tptr++); } } else { back = 0; } } state = 0; } break; default: { if(tsz + 1 < sizeof(tmp)) { *(tptr++) = *sptr; tsz++; } else { back = 0; } } } } break; case 3: { $? ". nach backslash" switch(*sptr) { case '\\': case '$': case '/': { if(dsz + 1 < sz) { *(dptr++) = *sptr; dsz++; } else { back = 0; } } break; default: { if(dsz + 2 < sz) { *(dptr++) = '\\'; *(dptr++) = *sptr; dsz++; dsz++; } else { back = 0; } } break; } state = 0; } break; default: { $? ". default" switch(*sptr) { case '$': { state = 1; } break; case '\\': { if(fnsbs && fn) { state = 0; if(dsz + 1 < sz) { *(dptr++) = *sptr; dsz++; } else { back = 0; } } else { state = 3; } } break; case '/' : { state = 0; if(dsz + 1 < sz) { *(dptr++) = fn_sep[0]; dsz++; } else { back = 0; } } break; default: { state = 0; if(dsz + 1 < sz) { *(dptr++) = *sptr; dsz++; } else { back = 0; } } break; } } break; } sptr++; } *dptr = (char)0; } $? "- kAppTransformString %d", back return back; } int dkapp_transform_string DK_P4(dk_app_t *,app,char *,dest,size_t,sz,char *,src) { int back; back = dkapp_transform_string_ext1(app,dest,sz,src,0); return back; } /** Find multiple strings. @param app Application. @param f String finder data listing key names and default texts. @param table String table name. @param logenab Flag: Internal Logging enabled. */ static void my_find_multi DK_P4(dk_app_t *, app, dk_string_finder_t *, f, char *, table,int,logenab) { dk_string_finder_t *ptr; stt_entry *stteptr; dk_stt_t *sttptr; int found; char *errmsgs[3]; found = 0; $? "+ dkapp_find_multi %s %s %s", TR_PTR(app), TR_PTR(f), TR_STR(table) if(app && f && table) { stteptr = find_stt_entry(app,table); if(stteptr) { $? ". table entry found" sttptr = stteptr->st; if(sttptr) { $? ". table entry contains string table" ptr = f; found = 1; while((ptr->key) && (ptr->value_pointer) && (ptr->default_value)) { *(ptr->value_pointer) = dkstt_find(sttptr, (ptr->key), (ptr->default_value)); ptr++; } } } } if(!found) { $? ". no matching string table found" if(f) { $? ". using default values" ptr = f; while((ptr->key) && (ptr->value_pointer) && (ptr->default_value)) { *(ptr->value_pointer) = (ptr->default_value); ptr++; } } /* ERROR NO STRING TABLE FOUND */ if(logenab) { errmsgs[0] = open_and_close_strings[12]; errmsgs[1] = table; errmsgs[2] = open_and_close_strings[13]; dkapp_log_msg(app,DK_LOG_LEVEL_WARNING,errmsgs,3); } } else { /* DEBUG STRING TABLE FOUND */ if(logenab) { errmsgs[0] = open_and_close_strings[14]; errmsgs[1] = table; errmsgs[2] = open_and_close_strings[15]; dkapp_log_msg(app,DK_LOG_LEVEL_DEBUG,errmsgs,3); } } $? "- dkapp_find_multi" } void dkapp_find_multi DK_P3(dk_app_t *, app, dk_string_finder_t *, f, char *, table) { my_find_multi(app,f,table,1); } /** Pointer to character buffer. */ typedef char *PCHR; void dkapp_init_key_value DK_P5(dk_app_t *,a,dk_key_value_t *,k,size_t,s,char *,n,char **,b) { dk_string_finder_t *strf, *strfp; char **ptr; dk_key_value_t *kvp; size_t cc; $? "+ dkapp_init_key_value %s %s %lu %s %s", TR_PTR(a), TR_PTR(k), (unsigned long)s, TR_STR(n), TR_PTR(b) if (k) { if (s) { if (b) { $? ". parameters ok" strf = NULL; if(a && n) { strf = dk_new(dk_string_finder_t,(s+1)); } if(a && n && strf) { $? ". use dkapp_find_multi" strfp = strf; kvp = k; ptr = b; cc = s; while (cc--) { strfp->key = kvp->key; strfp->default_value = kvp->value; strfp->value_pointer = ptr; strfp++; kvp++; ptr++; } strf[s].key = NULL; strf[s].default_value = NULL; strf[s].value_pointer = NULL; my_find_multi(a,strf,n,1); } else { $? ". initialize from defaults" kvp = k; ptr = b; cc = s; while (cc--) { *(ptr++) = (kvp++)->value; } } if(strf) { dk_delete(strf); strf = NULL; } } } } $? "- dkapp_init_key_value" } char ** dkapp_find_key_value DK_P4(dk_app_t *,a,dk_key_value_t *,k,size_t,s,char *,n) { char **back = NULL; $? "+ dkapp_find_key_value %s %s %lu",TR_PTR(a),TR_PTR(k),(unsigned long)s if (k) { if (s) { $? ". parameters ok" back = dk_new(PCHR,s); if (back) { $? ". memory ok" dkapp_init_key_value(a,k,s,n,back); } else { $? "! no memory" dkapp_err_memory(a,sizeof(PCHR),s); } } } $? "- dkapp_find_key_value %s", TR_PTR(back) return back; } /** Find a string from a string table. @param app Application. @param table String table name. @param key Key to search for. @param def Default text if no matching text is found. @param logenab Flag: Internal logging enabled. */ static char * my_find_string DK_P5(dk_app_t *,app,char *,table,char *,key,char *,def,int,logenab) { char *back = NULL; stt_entry *stteptr; char *errmsgs[3]; $? "+ dkapp_find_string %s %s %s %s", TR_PTR(app), TR_STR(table), TR_STR(key), TR_STR(def) if(app && table && key) { stteptr = find_stt_entry(app,table); if(stteptr) { if(stteptr->st) { back = dkstt_find((stteptr->st),key,def); } else { /* ERROR NO STRING TABLE FOUND */ if(logenab) { errmsgs[0] = open_and_close_strings[12]; errmsgs[1] = table; errmsgs[2] = open_and_close_strings[13]; dkapp_log_msg(app,DK_LOG_LEVEL_WARNING,errmsgs,3); } } } else { /* ERROR NO STRING TABLE FOUND */ if(logenab) { errmsgs[0] = open_and_close_strings[4]; errmsgs[1] = table; errmsgs[2] = open_and_close_strings[5]; dkapp_log_msg(app,DK_LOG_LEVEL_DEBUG,errmsgs,3); } } } if(!back) { back = def; } $? "- dkapp_find_string %s", TR_STR(back) return back; } char * dkapp_find_string DK_P4(dk_app_t *,app,char *,table,char *,key,char *,def) { char *back; back = my_find_string(app,table,key,def,1); return back; } int dkapp_get_argc DK_P1(dk_app_t *,a) { int back = 0; if(a) { back = (a->a).a.argc; } return back; } char **dkapp_get_argv DK_P1(dk_app_t *,a) { char **back = NULL; if(a) { back = (a->a).a.argv; } return back; } /** Write buffer contents to output file (used to show help text). @param a Application. @param b1 Source buffer. @param b2 Temporary buffer for conversion. @param sz Size of \a b1 and \a b2. @param mctu Flag: Conversion to UTF-8 necessary. @param f Output file. @param cp Codepage to use. */ static void buffer_to_file DK_P7(dk_app_t *,a, char *,b1, char *,b2, size_t, sz, int,mctu, FILE *,f, unsigned char *,cp) { dk_udword udw; char obuffer[16]; size_t i, j; switch((a->loc).es) { case DK_APP_ENCODING_UTF8: { if(mctu) { for(i = 0; i < sz; i++) { udw = ((dk_udword)((unsigned char)(b1[i]))) & 0x000000FFUL; j = dkenc_uc2utf8(udw, (unsigned char *)obuffer, sizeof(obuffer)); if(j > 0) { (void)fwrite((void *)obuffer, 1, j, f); } } } else { (void)fwrite(b1,1,sz,f); } } break; default: { #if DK_HAVE_CODEPAGES if(cp) { for(i = 0; i < sz; i++) { b2[i] = dkcp_convert(cp, b1[i]); } (void)fwrite(b2,1,sz,f); } else { (void)fwrite(b1,1,sz,f); } #else (void)fwrite(b1,1,sz,f); #endif } break; } } void dkapp_stdout DK_P2(dk_app_t *,app, char *,s) { if(s) { if(app) { switch((app->loc).es) { case DK_APP_ENCODING_UTF8: { fputs(s, stdout); } break; default: { #if DK_HAVE_CODEPAGES dkcp_fputs(stdout, (app->l).o.c, s); #else fputs(s, stdout); #endif } break; } } else { fputs(s, stdout); } } } void dkapp_stderr DK_P2(dk_app_t *, app, char *,s) { if(s) { if(app) { switch((app->loc).es) { case DK_APP_ENCODING_UTF8: { fputs(s, stderr); } break; default: { #if DK_HAVE_CODEPAGES dkcp_fputs(stderr, (app->l).e.c, s); #else fputs(s, stderr); #endif } break; } } else { fputs(s, stderr); } } } void dkapp_fputs DK_P3(dk_app_t *, app, char *,s, FILE *,f) { if(s) { if(app) { switch((app->loc).es) { case DK_APP_ENCODING_UTF8: { fputs(s, f); } break; default: { #if DK_HAVE_CODEPAGES dkcp_fputs(f, (app->l).f.c, s); #else fputs(s, f); #endif } break; } } else { fputs(s, f); } } } size_t dkapp_prlen DK_P2(dk_app_t *,app, char *,s) { size_t back = 0; size_t used, sl, newlength, summary_used; dk_udword uw; int cc; if(s) { if(app) { switch((app->loc).es) { case DK_APP_ENCODING_UTF8: { /* convert UTF-8 to UC and count */ cc = 1; summary_used = 0; sl = strlen(s); while((cc) && (sl > summary_used)) { used = 0; uw = 0UL; if(dkenc_utf82uc(&uw, (dk_ubyte *)(&(s[summary_used])), (sl - summary_used), &used)) { back++; newlength = summary_used + used; if(newlength > summary_used) { summary_used = newlength; if(summary_used >= sl) { cc = 0; } } else { cc = 0; } } else { cc = 0; } } } break; default: { back = strlen(s); } break; } } else { back = strlen(s); } } return back; } void dkapp_help DK_P3(dk_app_t *,a,char *,filename,char **,str) { int found = 0; /* help file found ? */ char buffer[128], b2[128]; /* buffers for read/write operations */ int bytes; /* number of bytes read */ dk_stream_t *strm; /* stream to read input file */ char **ptr; /* pointer running through array str */ int subdirtype; /* does subdirectory contain encoding ? */ int mctu; /* must convert to UTF-8 */ subdirtype = 0; mctu = 0; if((a) && (filename) && (str)) { found = 0; strm = my_read_file_ext1(a,filename,1,1,&subdirtype); // attempt to read file if(strm) { if((a->loc).e) { if((a->loc).es == DK_APP_ENCODING_UTF8) { if(!(subdirtype & DK_APP_PNC_ENCODING)) { mctu = 1; } } } while((bytes = dkstream_read(strm,buffer,sizeof(buffer))) > 0) { /* write help text to log file */ buffer_to_file(a, buffer, b2, bytes, mctu, (a->l).f.t, (a->l).f.c); /* write help text to standard output */ buffer_to_file(a, buffer, b2, bytes, mctu, stdout, (a->l).o.c); found = 1; } dkstream_close(strm); if(found) { fputc('\n', stdout); if((a->l).f.t) { fputc('\n', (a->l).f.t); } } } // if file was not found use default text if(!found) { ptr = str; while(*ptr) { dkapp_stdout(a, *ptr); fputc('\n', stdout); if((a->l).f.t) { dkapp_fputs(a, *ptr, (a->l).f.t); fputc('\n', (a->l).f.t); } ptr++; } } } } /** Open files for binary writing. */ static char wb[] = { "wb" }; dk_stream_t * dkapp_write_file DK_P2(dk_app_t *, app, char *, filename) { dk_stream_t *back = NULL; dk_stream_suffix_t *suffix_ptr, *sptr2; dk_stream_open_fct_t *fct; char *buffer; size_t lgt, maxlgt; if(app && filename) { suffix_ptr = dkstream_get_write_suffixes(); sptr2 = suffix_ptr; maxlgt = 0; while((sptr2->suffix) && (sptr2->fct)) { lgt = strlen(sptr2->suffix); if(lgt > maxlgt) maxlgt = lgt; sptr2++; } maxlgt += strlen(filename); maxlgt++; buffer = dk_new(char,maxlgt); if(buffer) { sptr2 = suffix_ptr; while((sptr2->suffix) && (sptr2->fct) && (!back)) { fct = sptr2->fct; strcpy(buffer, filename); strcat(buffer, sptr2->suffix); app->relaxed_fopen_reason = 0; back = ((*fct)(buffer, wb, app->relaxed_fopen_check, &(app->relaxed_fopen_reason))); if((!back) && (app->relaxed_fopen_reason)) { dkapp_err_nowrite(app, buffer, app->relaxed_fopen_reason); } sptr2++; } dk_delete(buffer); } } return back; } /** Report memory usage. @param a Application. */ static void memory_usage DK_P1(dk_app_t *,a) { char buffer[64], *ptr; unsigned long h, l; h = l = 0UL; h = dkmem_get_track(1); l = dkmem_get_track(0); if(h) { sprintf( buffer, "%32lg", (4294967296.0*dkma_l_to_double(h)+dkma_l_to_double(l)) ); } else { sprintf(buffer, "%lu", l); } ptr = dkstr_start(buffer, NULL); if(ptr) { char *logmsgs[4]; logmsgs[0] = open_and_close_strings[30]; logmsgs[1] = ptr; logmsgs[2] = open_and_close_strings[31]; dkapp_log_msg(a,DK_LOG_LEVEL_DEBUG,logmsgs,3); } } /** Open files for writing. */ static char str_w[] = { "w" }; void dkapp_close DK_P1(dk_app_t *, a) { char *cptr, **argptr; int i; dk_preference_t *pptr; stt_entry *stteptr; char *logmsgs[3]; long maxpathlen; char *filename; #if !DK_HAVE_WINREG_H FILE *outputfile; int print_it; dk_preference_t *ppt2; #endif $? "+ dkapp_close %s", TR_PTR(a) if(a) { if((a->random).seed_file_name) { cptr = (a->random).seed_file_name; dk_delete(cptr); (a->random).seed_file_name = NULL; } (a->random).prng_type = DK_RAND_TYPE_NONE; if((a->n).a) { logmsgs[0] = open_and_close_strings[2]; logmsgs[1] = (a->n).a; logmsgs[2] = open_and_close_strings[3]; dkapp_log_msg(a,DK_LOG_LEVEL_PROGRESS,logmsgs,3); memory_usage(a); } /* Free string table space */ if(((a->loc).s) && ((a->loc).si)) { dksto_it_reset((a->loc).si); while((stteptr = (stt_entry *)dksto_it_next((a->loc).si)) != NULL) { stt_entry_free(stteptr); } dksto_close((a->loc).s); (a->loc).s = NULL; (a->loc).si = NULL; } /* Write preferences back to file */ #if !DK_HAVE_WINREG_H if(((a->d).h) && ((a->n).a) && (((a->p).unc) || ((a->p).prf))) { maxpathlen = dksf_get_maxpathlen(); if(maxpathlen < 0L) { maxpathlen = 1024L; } filename = dk_new(char,maxpathlen); if(filename) { if((strlen((a->d).h) + strlen(defaults_sub) + strlen((a->n).a) + 2) < (unsigned long)maxpathlen) { strcpy(filename, (a->d).h); strcat(filename, fn_sep); strcat(filename, defaults_sub); strcat(filename, fn_sep); strcat(filename, (a->n).a); #if NO_FOPEN_CHECKING #if DK_HAVE_LARGEFILE64_SOURCE && DK_HAVE_FOPEN64 outputfile = fopen64(filename, str_w); #else outputfile = fopen(filename, str_w); #endif #else a->relaxed_fopen_reason = 0; outputfile = dksf_msfo(filename, str_w, a->relaxed_fopen_check, &(a->relaxed_fopen_reason)); if((!outputfile) && (a->relaxed_fopen_reason)) { dkapp_err_nowrite(a, filename, a->relaxed_fopen_reason); } #endif if(outputfile) { if(!((a->p).unc)) { if(((a->p).u) && ((a->p).ui)) { dksto_it_reset((a->p).ui); while((pptr = (dk_preference_t *)dksto_it_next((a->p).ui)) != NULL) { if((pptr->n) && (pptr->v)) { if((pptr->p) & 2) { print_it = 1; if(((a->p).a) && ((a->p).ai)) { ppt2 = (dk_preference_t *)dksto_it_find_like((a->p).ai, pptr->n, 1); if(ppt2) { print_it = 0; } } if(print_it) { fputs(pptr->n, outputfile); fputs("\t=\t", outputfile); fputs(pptr->v, outputfile); fputc('\n', outputfile); } } } } dksto_it_reset((a->p).ai); while((pptr = (dk_preference_t *)dksto_it_next((a->p).ai)) != NULL) { if((pptr->n) && (pptr->v)) { fputs(pptr->n, outputfile); fputs("\t=\t", outputfile); fputs(pptr->v, outputfile); fputc('\n', outputfile); } } } } fclose(outputfile); } if((a->p).unc) { dksf_remove_file(filename); } } dk_delete(filename); } } #endif if((a->d).pt) { if(!(((a->l).max) > (a->keep_temp_dir))) { /* INFO temp dir not deleted */ logmsgs[0] = open_and_close_strings[28]; logmsgs[1] = (a->d).pt; logmsgs[2] = open_and_close_strings[29]; dkapp_log_msg(a,DK_LOG_LEVEL_WARNING,logmsgs,3); } } /* Close log system */ if((a->l).f.t) { fclose((a->l).f.t); (a->l).f.t = NULL; } if((a->l).f.n) { if(((a->l).max) > ((a->l).f.k)) { dksf_remove_file((a->l).f.n); } cptr = (a->l).f.n; dk_delete(cptr); (a->l).f.n = NULL; } #if DK_HAVE_SYSLOG if((a->l).s.o) { closelog(); (a->l).s.o = 0; } #endif if((a->l).o.c) { cptr = (char *)((a->l).o.c) ; dk_delete(cptr); } (a->l).o.c = NULL; if((a->l).e.c) { cptr = (char *)((a->l).e.c) ; dk_delete(cptr); } (a->l).e.c = NULL; if((a->l).f.c) { cptr = (char *)((a->l).f.c) ; dk_delete(cptr); } (a->l).f.c = NULL; /* Release names */ if((a->loc).l) { cptr = (a->loc).l; dk_delete(cptr); } (a->loc).l = NULL; if((a->loc).r) { cptr = (a->loc).r; dk_delete(cptr); } (a->loc).r = NULL; if((a->loc).e) { cptr = (a->loc).e; dk_delete(cptr); } (a->loc).e = NULL; if((a->x).d) { cptr = (a->x).d; dk_delete(cptr); } if((a->x).f) { cptr = (a->x).f; dk_delete(cptr); } (a->x).d = NULL; (a->x).f = NULL; if((a->d).etc) { cptr = (a->d).etc; dk_delete(cptr); (a->d).etc = NULL; } if((a->d).pt) { if(((a->l).max) > (a->keep_temp_dir)) { $? ". remove temp directory" (void)dksf_remove_directory((a->d).pt); } else { $? ". keep temp diectory" } cptr = (a->d).pt; dk_delete(cptr); } if((a->d).a) { cptr = (a->d).a; dk_delete(cptr); } if((a->d).s) { cptr = (a->d).s; dk_delete(cptr); } if((a->d).t) { cptr = (a->d).t; dk_delete(cptr); } if((a->d).h) { cptr = (a->d).h; dk_delete(cptr); } /* if((a->n).a) { cptr = (a->n).a; dk_delete(cptr); } */ if((a->n).h) { cptr = (a->n).h; dk_delete(cptr); } if((a->n).u) { cptr = (a->n).u; dk_delete(cptr); } /* (a->n).a = NULL; */ (a->n).h = NULL; (a->n).u = NULL; (a->d).s = NULL; (a->d).a = NULL; (a->d).h = NULL; (a->d).t = NULL; (a->d).pt = NULL; /* Release preferences data */ if(((a->p).a) && ((a->p).ai)) { dksto_it_reset((a->p).ai); while((pptr = (dk_preference_t *)dksto_it_next((a->p).ai)) != NULL) { dkpref_delete(pptr); } dksto_close((a->p).a); (a->p).a = NULL; (a->p).ai = NULL; } if(((a->p).c) && ((a->p).ci)) { dksto_it_reset((a->p).ci); while((pptr = (dk_preference_t *)dksto_it_next((a->p).ci)) != NULL) { dkpref_delete(pptr); } dksto_close((a->p).c); (a->p).c = NULL; (a->p).ci = NULL; } #if DK_HAVE_WINREG_H if(((a->p).what) & 1) { RegCloseKey((a->p).hklm_all); } if(((a->p).what) & 2) { RegCloseKey((a->p).hklm_app); } if(((a->p).what) & 4) { RegCloseKey((a->p).hkcu_all); } if(((a->p).what) & 8) { RegCloseKey((a->p).hkcu_app); } if((a->p).unc) { maxpathlen = 1024L; filename = dk_new(char,maxpathlen); if(filename) { if((strlen((a->n).a) + strlen(hkcu) + 1) < (size_t)maxpathlen) { strcpy(filename, hkcu); strcat(filename, fn_sep); strcat(filename, (a->n).a); RegDeleteKey(HKEY_CURRENT_USER, filename); } dk_delete(filename); } } #else if(((a->p).u) && ((a->p).ui)) { dksto_it_reset((a->p).ui); while((pptr = (dk_preference_t *)dksto_it_next((a->p).ui)) != NULL) { dkpref_delete(pptr); } dksto_close((a->p).u); (a->p).u = NULL; (a->p).ui = NULL; } if(((a->p).s) && ((a->p).si)) { dksto_it_reset((a->p).si); while((pptr = (dk_preference_t *)dksto_it_next((a->p).si)) != NULL) { dkpref_delete(pptr); } dksto_close((a->p).s); (a->p).s = NULL; (a->p).si = NULL; } #endif if((a->n).g) { cptr = (a->n).g ; dk_delete(cptr); } (a->n).g = NULL; if((a->n).a) { cptr = (a->n).a ; dk_delete(cptr); } (a->n).a = NULL; /* Release command line args */ if( (a->a).a.argv ) { argptr = (a->a).a.argv ; for(i = 0; i < (a->a).o.argc; i++) { argptr[i] = NULL; } dk_delete(argptr); } if( (a->a).o.argv ) { argptr = (a->a).o.argv ; if(argptr) { for(i = 0; i < (a->a).o.argc; i++) { cptr = argptr[i]; if(cptr) dk_delete(cptr); } dk_delete(argptr); } } /* Finally delete the application itself */ app_init_empty(a); dk_delete(a); } $? "- dkapp_close" } #if !DK_HAVE_WINREG_H /** Default configuration file name. */ static char local_default_configuration[] = { #if DK_HAVE_FEATURE_BACKSLASH "C:\\ETC\\ALL.DEF" #else DK_SYSCONFDIR "/appdefaults" #endif }; #endif int dkapp_get_min_loglevel DK_P1(dk_app_t *,a) { int back = DK_LOG_LEVEL_NONE; if(a) { back = (a->l).o.m; if(back < ((a->l).e.m)) { back = (a->l).e.m; } if(back < ((a->l).f.m)) { back = (a->l).f.m; } #if DK_HAVE_SYSLOG if(back < ((a->l).s.m)) { back = (a->l).s.m; } #endif } return back; } /** Preference key: Ignore different owners for symlink and target. */ static char key_sec_ign_file_owner[] = { "/sec/ign/link-owner" }; /** Preference key: Ignore symlinks group-writable directory. */ static char key_sec_ign_dir_group_writable[] = { "/sec/ign/dir-group-wriable" }; /** Preference key: Ignore symlinks in world-writable directories. */ static char key_sec_ign_dir_world_writable[] = { "/sec/ign/dir-world-wriable" }; /** Keywords to choose an IDE style. */ static char *ide_keys[] = { (char *)"g$cc", (char *)"ms$vc", (char *)"w$orkshop", (char *)"t$asm", NULL }; /** String table name for messages from this module. */ static char str_dkapp[] = { "dkapp" }; /** String table name for error messages. */ static char str_dkappe[] = { "dkappe" }; /** String table name for debug messages. */ static char str_dkappd[] = { "dkappd" }; int dkapp_ide_type DK_P1(char *,str) { int back = 0; $? "+ dkapp_ide_type %s", TR_STR(str) if(str) { back = 1 + dkstr_array_abbr(ide_keys,str,'$',0); } $? "- dkapp_ide_type %d", back return back; } /** Open an application. @param argc Number of command line arguments. @param argv Command line arguments array. @param grname Application group name. @param etc System configuration directory (/etc or /usr/local/etc). @param sil Flag: Run silently @param nostdio Combination of DK_APP_LOG_NO_STDERR/DK_APP_LOG_NO_STDOUT. @return Pointer to new application on success, NULL on error. */ static dk_app_t * my_app_open DK_P6(int,argc,char **,argv,char *,grname,char *,etc,int,sil,int,nostdio) { dk_app_t *back = NULL; int i, j, my_set_silent; char *cptr, *cptr2, **argptr, **argptr2; long maxpathlen, mypid; char *buffer, *buffer2, *bptr; dk_stat_t st; char *logmsgs[3]; #if DK_HAVE_WINREG_H HKEY hkTemp; PHKEY phkSubkey; DWORD disp; LONG retval; #endif #if DK_HAVE_CODEPAGES dk_stream_t *cp_stream; #endif $? "+ dkapp_open argc=%d argv=%s gr=%s etc=%s sil=%d nos=%d",argc,TR_PTR(argv),TR_STR(grname),TR_STR(etc),sil,nostdio maxpathlen = dksf_get_maxpathlen(); if(maxpathlen < 0L) { maxpathlen = 1024L; } buffer = dk_new(char,maxpathlen); buffer2 = dk_new(char,maxpathlen); if(argc && argv) { my_set_silent = dkapp_silence_check(argc,argv); if(sil) { my_set_silent = 1; } back = dk_new(dk_app_t,1); if(back) { /* Initialize member variables */ app_init_empty(back); $? ". set_silent=%d my_set_silent=%d sil=%d", set_silent, my_set_silent, sil if(set_silent || my_set_silent || sil) { (back->l).f.k = DK_LOG_LEVEL_NONE; (back->l).f.m = DK_LOG_LEVEL_NONE; (back->l).e.m = DK_LOG_LEVEL_NONE; (back->l).o.m = DK_LOG_LEVEL_NONE; } if(nostdio) { (back->l).nostdio = nostdio; } /* Copy command line arguments */ if(argc > 0) { argptr = dk_new(CHARPTR,argc); if(argptr) { for(i = 0; i < argc; i++) { argptr[i] = NULL; if(argv[i]) { argptr[i] = dkstr_dup(argv[i]); } } (back->a).o.argc = argc; (back->a).o.argv = argptr; argptr2 = dk_new(CHARPTR,argc); if(argptr2) { for(i = 0; i < argc; i++) { argptr2[i] = argptr[i]; } (back->a).a.argc = argc; (back->a).a.argv = argptr2; } } } /* Find names and some directories */ { if(grname) { (back->n).g = dkstr_dup(grname); } if(etc) { (back->d).etc = dkstr_dup(etc); if((back->d).etc) { dksf_correct_fnsep((back->d).etc); } } if(buffer) { if(dksf_get_uname(buffer,maxpathlen)) { (back->n).u = dkstr_dup(buffer); } if(dksf_get_hostname(buffer,maxpathlen)) { (back->n).h = dkstr_dup(buffer); } if(argc > 0) { if(argv[0]) { bptr = dkstr_rchr(argv[0], fn_sep[0]); if(bptr) bptr++; else bptr = argv[0]; (back->n).a = dkstr_dup(bptr); if((back->n).a) { bptr = dkstr_rchr((back->n).a, '.'); if(bptr) { *bptr = (char)0; } } } } if(dksf_get_home(buffer,maxpathlen)) { (back->d).h = dkstr_dup(buffer); } if(dksf_get_tempdir(buffer,maxpathlen)) { (back->d).t = dkstr_dup(buffer); } if(argc > 0) { if(argv[0]) { if(buffer2) { if(dksf_getcwd(buffer2,maxpathlen)) { if(dksf_get_executable(buffer,maxpathlen,buffer2,argv[0],1)) { (back->x).f = dkstr_dup(buffer); bptr = dkstr_rchr(buffer, fn_sep[0]); if(bptr) { *bptr = '\0'; (back->x).d = dkstr_dup(buffer); } } } } } } if((back->x).d) { if((strlen((back->x).d) + 3) < (unsigned long)maxpathlen) { strcpy(buffer, (back->x).d); bptr = dkstr_rchr(buffer, fn_sep[0]); if(bptr) { bptr++; if(strcmp(bptr, bin_dir) == 0) { /* strcpy(bptr, lib_dir); */ strcpy(bptr, share_dir); (back->d).s = dkstr_dup(buffer); if((strlen(buffer) + strlen((back->n).a) + 1) < (size_t)maxpathlen) { strcat(buffer, fn_sep); strcat(buffer, (back->n).a); (back->d).a = dkstr_dup(buffer); } } else { (back->d).a = dkstr_dup(buffer); (back->d).s = dkstr_dup(buffer); } } } } } } /* Initialize preferences management */ #if DK_HAVE_WINREG_H hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_LOCAL_MACHINE, hklm, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (back->p).hklm_all = hkTemp; (back->p).what |= 1; } if(buffer && ((back->n).a)) { if((strlen(hklm) + strlen((back->n).a) + 1) < (size_t)maxpathlen) { strcpy(buffer, hklm); strcat(buffer, backslash); strcat(buffer, (back->n).a); hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_LOCAL_MACHINE, buffer, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (back->p).hklm_app = hkTemp; (back->p).what |= 2; } } } hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_CURRENT_USER, hkcu, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (back->p).hkcu_all = hkTemp; (back->p).what |= 4; } if(buffer && ((back->n).a)) { if((strlen(hkcu) + strlen((back->n).a) + 1) < (size_t)maxpathlen) { strcpy(buffer, hkcu); strcat(buffer, backslash); strcat(buffer, (back->n).a); hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_CURRENT_USER, buffer, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (back->p).hkcu_app = hkTemp; (back->p).what |= 8; } } } #else (back->p).s = dksto_open(DK_STO_SIZE_TINY); if((back->p).s) { (back->p).si = dksto_it_open((back->p).s); if((back->p).si) { dksto_set_comp((back->p).s, dkapp_pref_compare, 0); dksto_use_trees((back->p).s, 0); } else { dksto_close((back->p).s); (back->p).s = NULL; } } (back->p).u = dksto_open(DK_STO_SIZE_TINY); if((back->p).u) { (back->p).ui = dksto_it_open((back->p).u); if((back->p).ui) { dksto_set_comp((back->p).u, dkapp_pref_compare, 0); dksto_use_trees((back->p).u, 0); } else { dksto_close((back->p).u); (back->p).u = NULL; } } #endif (back->p).a = dksto_open(DK_STO_SIZE_TINY); if((back->p).a) { (back->p).ai = dksto_it_open((back->p).a); if((back->p).ai) { dksto_set_comp((back->p).a, dkapp_pref_compare, 0); dksto_use_trees((back->p).a, 0); } else { dksto_close((back->p).a); (back->p).a = NULL; } } (back->p).c = dksto_open(DK_STO_SIZE_TINY); if((back->p).c) { (back->p).ci = dksto_it_open((back->p).c); if((back->p).ci) { dksto_set_comp((back->p).c, dkapp_pref_compare, 0); dksto_use_trees((back->p).c, 0); } else { dksto_close((back->p).c); (back->p).c = NULL; } } argptr = (back->a).a.argv; for(i = 0; i < (back->a).a.argc; i++) { cptr = argptr[i]; if(cptr[0] == '-') { if(cptr[1] == '-') { if(cptr[2] == '/') { for(j = i; j < ((back->a).a.argc - 1); j++) { argptr[j] = argptr[j+1]; } (back->a).a.argc = (back->a).a.argc - 1 ; cptr2 = dkstr_chr(cptr,'='); if(cptr2) { *(cptr2++) = (char)0; add_pref_to_list((back->p).c, (back->p).ci, &(cptr[2]), cptr2, 7); } i--; } } } } /* Read preferences from files */ #if !DK_HAVE_WINREG_H if(buffer) { if((back->d).s) { $? ". have shared directory %s", (back->d).s if(((back->p).s) && ((back->p).si)) { $? ". storage ok" if((strlen((back->d).s) + strlen(appdef) + 1) < (unsigned long)maxpathlen) { $? ". name length ok" strcpy(buffer, (back->d).s); strcat(buffer, fn_sep); strcat(buffer, appdef); $? ". read_cfg %s", buffer read_cfg( (back->p).s, (back->p).si, buffer, (back->n).u, (back->n).a, (back->n).h, 0 ); } if((back->n).a) { if((strlen((back->d).s)+strlen(appdef)+strlen((back->n).a)+2) < (unsigned long)maxpathlen) { strcpy(buffer, (back->d).s); strcat(buffer, fn_sep); strcat(buffer, appdef); strcat(buffer, dot); strcat(buffer, (back->n).a); $? ". read_cfg %s", buffer read_cfg( (back->p).s, (back->p).si, buffer, (back->n).u, (back->n).a, (back->n).h, 2 ); } } } } if(((back->p).s) && ((back->p).si)) { $? ". read_cfg %s", local_default_configuration read_cfg( (back->p).s, (back->p).si, local_default_configuration, (back->n).u, (back->n).a, (back->n).h, 0 ); #if DK_HAVE_FEATURE_BACKSLASH if((back->n).a) { if((strlen(local_default_configuration) + strlen((back->n).a) + 4) < maxpathlen) { strcpy(buffer, local_default_configuration); cptr = dkstr_chr(buffer, fn_sep[0]); if(cptr) { cptr++; strcpy(cptr, (back->n).a); strcat(cptr, ".DEF"); $? ". read_cfg %s", buffer read_cfg( (back->p).s, (back->p).si, buffer, (back->n).u, (back->n).a, (back->n).h, 2 ); } } } #else if((back->n).a) { if((strlen((back->n).a) + strlen(local_default_configuration) + 2) < (unsigned long)maxpathlen) { } strcpy(buffer, local_default_configuration); strcat(buffer, "."); strcat(buffer, (back->n).a); $? ". read_cfg %s", buffer read_cfg( (back->p).s, (back->p).si, buffer, (back->n).u, (back->n).a, (back->n).h, 2 ); } #endif } if((back->d).h) { $? ". have home directory" if((strlen((back->d).h) + strlen(defaults_sub) + 1) < (unsigned long)maxpathlen) { strcpy(buffer, (back->d).h); strcat(buffer, fn_sep); strcat(buffer, defaults_sub); dksf_mkdir(buffer, DK_PERM_CREATE_PROTECTED); if((strlen(buffer) + strlen(all_files) + 1) < (unsigned long)maxpathlen) { strcat(buffer, fn_sep); strcat(buffer, all_files); if(((back->p).u) && ((back->p).ui)) { $? ". read_cfg %s", buffer read_cfg( (back->p).u, (back->p).ui, buffer, (back->n).u, (back->n).a, (back->n).h, 4 ); } } strcpy(buffer, (back->d).h); strcat(buffer, fn_sep); strcat(buffer, defaults_sub); if((back->n).a) { if((strlen(buffer) + strlen((back->n).a) + 1) < (unsigned long)maxpathlen) { strcat(buffer, fn_sep); strcat(buffer, (back->n).a); if(((back->p).u) && ((back->p).ui)) { $? ". read_cfg %s", buffer read_cfg( (back->p).u, (back->p).ui, buffer, (back->n).u, (back->n).a, (back->n).h, 6 ); } } } } } } #endif /* Correct file and dir names */ $? "buffer = %s , buffer2 = %s", TR_PTR(buffer), TR_PTR(buffer2) if(buffer && buffer2) { $? ". trying to retrieve fopen security check settings" if(dkapp_get_pref(back,key_sec_ign_file_owner,buffer,maxpathlen,(~(DK_APP_PREF_EXCL_CMD)))) { if(dkstr_is_on(buffer)) { back->relaxed_fopen_check |= DK_SF_SEC_OWNER; } } if(dkapp_get_pref(back,key_sec_ign_dir_world_writable,buffer,maxpathlen,(~(DK_APP_PREF_EXCL_CMD)))) { if(dkstr_is_on(buffer)) { back->relaxed_fopen_check |= DK_SF_SEC_WO; back->relaxed_fopen_check |= DK_SF_SEC_WG; } } else { if(dkapp_get_pref(back,key_sec_ign_dir_group_writable,buffer,maxpathlen,(~(DK_APP_PREF_EXCL_CMD)))) { if(dkstr_is_on(buffer)) { back->relaxed_fopen_check |= DK_SF_SEC_WG; } } } if(dkapp_get_pref(back,app_dir,buffer,maxpathlen,0)) { if(dkapp_transform_string_ext1(back,buffer2,maxpathlen,buffer,1)) { dksf_correct_fnsep(buffer2); if(dkstat_get(&st,buffer2)) { if((st.filetype & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { cptr = dkstr_dup(buffer2); if(cptr) { if((back->d).a) { cptr2 = (back->d).a; dk_delete(cptr2); (back->d).a = NULL; } (back->d).a = cptr; } } } } } if(dkapp_get_pref(back,shared_dir,buffer,maxpathlen,0)) { if(dkapp_transform_string_ext1(back,buffer2,maxpathlen,buffer,1)) { dksf_correct_fnsep(buffer2); if(dkstat_get(&st,buffer2)) { if((st.filetype & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { cptr = dkstr_dup(buffer2); if(cptr) { if((back->d).s) { cptr2 = (back->d).s; dk_delete(cptr2); (back->d).s = NULL; } (back->d).s = cptr; } } } } } if(dkapp_get_pref(back,tmp_dir,buffer,maxpathlen,0)) { if(dkapp_transform_string_ext1(back,buffer2,maxpathlen,buffer,1)) { dksf_correct_fnsep(buffer2); if(dkstat_get(&st,buffer2)) { if((st.filetype & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { cptr = dkstr_dup(buffer2); if(cptr) { if((back->d).t) { cptr2 = (back->d).t; dk_delete(cptr2); (back->d).t = NULL; } (back->d).t = cptr; } } } else { (void)dksf_mkdir(buffer2, DK_PERM_CREATE_DIR); if(dkstat_get(&st,buffer2)) { if((st.filetype & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { cptr = dkstr_dup(buffer2); if(cptr) { if((back->d).t) { cptr2 = (back->d).t; dk_delete(cptr2); (back->d).t = NULL; } (back->d).t = cptr; } } } } } } if((back->d).t) { if(dksf_have_getpid()) { $? ". have getpid" if((strlen((back->d).t) + 13) < (size_t)maxpathlen) { int cc; unsigned long ul; mypid = dksf_getpid(); cc = 1; ul = 0UL; do { sprintf( buffer, "%s%s%08lX.%03lu", (back->d).t, fn_sep, mypid, ul ); $? ". file name to test now \"%s\"", TR_STR(buffer) if(!dkstat_get(&st, buffer)) { $? ". no such file yet" (void)dksf_mkdir(buffer, DK_PERM_CREATE_DIR); if(dkstat_get(&st, buffer)) { $? ". name now exists" if(((st.filetype) & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { (back->d).pt = dkstr_dup(buffer); cc = 0; if(!((back->d).pt)) { dksf_remove_directory(buffer); } else { $? ". success" } } else { $? "! some problem" dksf_remove_directory(buffer); } } else { $? "! failed to create" /* make sure not to leave artefacts */ dksf_remove_directory(buffer); } } else { $? ". name already exists" } } while((cc == 1) && (!((back->d).pt)) && (++ul < 1000UL)); } else { $? ". name of temp directory too long" } } else { unsigned long myul; $? ". no getpid()" myul = 1UL; while(myul != 0UL) { if((strlen((back->d).t) + 13) < (size_t)maxpathlen) { sprintf(buffer2, "%08lX", myul); strcpy(buffer, (back->d).t); strcat(buffer, fn_sep); strcat(buffer, buffer2); strcat(buffer, dot_tmp); if(!dkstat_get(&st,buffer)) { (void)dksf_mkdir(buffer, DK_PERM_CREATE_DIR); if(dkstat_get(&st,buffer)) { if(((st.filetype) & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { cptr = dkstr_dup(buffer); if(cptr) { (back->d).pt = cptr; myul = 0UL; } else { dksf_remove_directory(buffer); myul = 0UL; } } else { myul++; } } else { myul++; } } else { myul++; } } else { myul = 0UL; } } } } #if DK_HAVE_CODEPAGES if(dkapp_get_pref(back,log_file_codepage,buffer,maxpathlen,0)) { if(strcmp(minus_sign, buffer)) { cp_stream = my_read_file(back, buffer, 0, 1); if(cp_stream) { (back->l).f.c = dkcp_open(cp_stream); dkstream_close(cp_stream); } cp_stream = NULL; } } if(dkapp_get_pref(back,log_stdout_codepage,buffer,maxpathlen,0)) { if(strcmp(minus_sign, buffer)) { cp_stream = my_read_file(back, buffer, 0, 1); if(cp_stream) { (back->l).o.c = dkcp_open(cp_stream); dkstream_close(cp_stream); } cp_stream = NULL; } } if(dkapp_get_pref(back,log_stderr_codepage,buffer,maxpathlen,0)) { if(strcmp(minus_sign, buffer)) { cp_stream = my_read_file(back, buffer, 0, 1); if(cp_stream) { (back->l).e.c = dkcp_open(cp_stream); dkstream_close(cp_stream); } cp_stream = NULL; } } #endif $? ". trying to retrieve /log/file/name" if(dkapp_get_pref(back,log_file_name,buffer,maxpathlen,0)) { if(dkapp_transform_string_ext1(back,buffer2,maxpathlen,buffer,1)) { dksf_correct_fnsep(buffer2); (back->l).f.n = dkstr_dup(buffer2); } } } /* Set up logging */ if(buffer) { char *appname; size_t lgt; int i; if(!(set_silent || my_set_silent || sil)) { if(dkapp_get_pref(back,log_file_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (back->l).f.m = i; } } if(dkapp_get_pref(back,log_file_keep,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (back->l).f.k = i; } } } i = 0; if(dkapp_get_pref(back,log_file_time,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i = 1; } } if(dkapp_get_pref(back,log_file_split,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i |= 2; } } (back->l).f.f = i; if(dkapp_get_pref(back,log_file_ide,buffer,maxpathlen,0)) { (back->l).f.ide_type = dkapp_ide_type(buffer); /* 1 + dkstr_array_abbr(ide_keys,buffer,'$',0); */ $? ". (back->l).f.ide_type = %d", (back->l).f.ide_type } if(!(set_silent || my_set_silent || sil)) { if(dkapp_get_pref(back,log_stdout_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (back->l).o.m = i; } } } i = 0; if(dkapp_get_pref(back,log_stdout_time,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i = 1; } } if(dkapp_get_pref(back,log_stdout_split,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i |= 2; } } (back->l).o.f = i; if(dkapp_get_pref(back,log_stdout_ide,buffer,maxpathlen,0)) { (back->l).o.ide_type = 1 + dkstr_array_abbr(ide_keys, buffer, '$', 0); $? ". (back->l).o.ide_type = %d", (back->l).o.ide_type } if(!(set_silent || my_set_silent || sil)) { if(dkapp_get_pref(back,log_stderr_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (back->l).e.m = i; } } } i = 0; if(dkapp_get_pref(back,log_stderr_time,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i = 1; } } if(dkapp_get_pref(back,log_stderr_split,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { i |= 2; } } (back->l).e.f = i; if(dkapp_get_pref(back,log_stderr_ide,buffer,maxpathlen,0)) { (back->l).e.ide_type = 1 + dkstr_array_abbr(ide_keys, buffer, '$', 0); $? ". (back->l).e.ide_type = %d", (back->l).e.ide_type } #if DK_HAVE_SYSLOG i = DK_APP_PREF_EXCL_CMD; i |= DK_APP_PREF_EXCL_PROG; i |= DK_APP_PREF_EXCL_USER; if(dkapp_get_pref(back,log_syslog_level,buffer,maxpathlen,i)) { i = get_log_level(buffer); if(i >= 0) { (back->l).s.m = i; } } #endif appname = (back->n).a; appname = (appname ? appname : app); lgt = strlen(appname) + strlen(suffix_log) + 1; if(dksf_have_getpid()) { lgt += 16; } if(lgt < (size_t)maxpathlen) { strcpy(buffer, appname); if(dksf_have_getpid()) { strcat(buffer, dot); appname = buffer; while(*appname) appname++; sprintf(appname, "%lu", (unsigned long)dksf_getpid()); } strcat(buffer, dot); strcat(buffer, suffix_log); } if(!((back->l).f.n)) { (back->l).f.n = dkstr_dup(buffer); } $? ". opening log file %s", TR_STR((back->l).f.n) if((back->l).f.n) { #if NO_FOPEN_CHECKING #if DK_HAVE_LARGEFILE64_SOURCE && DK_HAVE_FOPEN64 (back->l).f.t = fopen64((back->l).f.n, str_w); #else (back->l).f.t = fopen((back->l).f.n, str_w); #endif #else back->relaxed_fopen_reason = 0; (back->l).f.t = dksf_msfo((back->l).f.n, str_w, back->relaxed_fopen_check, &(back->relaxed_fopen_reason)); if((!((back->l).f.t)) && (back->relaxed_fopen_reason)) { dkapp_err_nowrite(back, (back->l).f.n, back->relaxed_fopen_reason); } #endif } #if DK_HAVE_SYSLOG appname = (back->n).a; appname = (appname ? appname : app); if((back->l).s.m > DK_LOG_LEVEL_NONE) { (back->l).s.o = 1; openlog(appname, (LOG_PID|LOG_CONS), LOG_USER); } #endif i = DK_APP_PREF_EXCL_USER | DK_APP_PREF_EXCL_SYSTEM; if(dkapp_get_pref(back,ui_lang,buffer,maxpathlen,i)) { save_lang(back,buffer); /* ##### es */ } else { int use_env_lang; use_env_lang = 1; if(dkapp_get_pref(back,ui_lang_env,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { use_env_lang = 1; } else { use_env_lang = 0; } } if(use_env_lang) { cptr = getenv("LANG"); if(cptr) { if(strlen(cptr) < (size_t)maxpathlen) { strcpy(buffer,cptr); save_lang(back,buffer); /* ##### es */ } } else { // check registry if available #if DK_HAVE_WINREG_H HKEY intkey; LONG intres; DWORD intType; DWORD intlen; char intchar[64]; char *intptr; char intc; intres = RegOpenKeyExA( HKEY_CURRENT_USER, "Control Panel\\International", (DWORD)0, KEY_READ, &intkey ); if(intres == ERROR_SUCCESS) { intType = REG_SZ; intlen = (DWORD)sizeof(intchar); intres = RegQueryValueExA( intkey, "sLanguage", NULL, &intType, (LPBYTE)intchar, &intlen ); if(intres == ERROR_SUCCESS) { if((intType == REG_SZ) || (intType == REG_EXPAND_SZ)) { if(intlen >= 2) { intchar[2] = '\0'; strcpy(buffer, intchar); intptr = buffer; while(*intptr) { intc = *intptr; if(isascii(intc)) { if(isupper(intc)) { *intptr = tolower(intc); } } intptr++; } save_lang(back,buffer); } } } RegCloseKey(intkey); } #endif } } else { if(dkapp_get_pref(back,ui_lang,buffer,maxpathlen,0)) { save_lang(back,buffer); /* ##### es */ } else { strcpy(buffer, default_language); save_lang(back,buffer); } } } if(dkapp_get_pref(back,storage_trees,buffer,maxpathlen,0)) { if(dkstr_is_on(buffer)) { dksto_use_trees(NULL,1); } else { dksto_use_trees(NULL,0); } } } cptr = (back->loc).l; if(cptr) { while(*cptr) { if(isupper(*cptr)) { *cptr = tolower(*cptr); } cptr++; } } cptr = (back->loc).r; if(cptr) { while(*cptr) { if(isupper(*cptr)) { *cptr = tolower(*cptr); } cptr++; } } cptr = (back->loc).e; if(cptr) { while(*cptr) { if(isupper(*cptr)) { *cptr = tolower(*cptr); } cptr++; } } /* Set up string table handling */ (back->loc).s = dksto_open(DK_STO_SIZE_TINY); if((back->loc).s) { (back->loc).si = dksto_it_open((back->loc).s); if((back->loc).si) { dksto_set_comp((back->loc).s, stt_entry_comp, 0); dksto_use_trees((back->loc).s, 0); } else { dksto_close((back->loc).s); (back->loc).s = NULL; } } my_find_multi(back,log_level_string_finder,str_dkapp,0); my_find_multi(back,open_and_close_finder,str_dkapp,0); if(!app_err_conf) { my_find_multi(back,app_err_find,str_dkappe,0); app_err_conf = 1; } /* Debug output */ if(grname && (!((back->n).g))) { dkapp_err_memory(back, sizeof(char), (1+strlen(grname))); } if(etc && (!((back->d).etc))) { dkapp_err_memory(back, sizeof(char), (1+strlen(etc))); } if(dkapp_get_min_loglevel(back) >= DK_LOG_LEVEL_DEBUG) { my_find_multi(back,debug_string_finder,str_dkappd,0); logmsgs[0] = debug_strings[0]; logmsgs[1] = (((back->n).u) ? ((back->n).u) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[1]; logmsgs[1] = (((back->n).a) ? ((back->n).a) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); if((back->n).g) { logmsgs[0] = debug_strings[19]; logmsgs[1] = (back->n).g; dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); } logmsgs[0] = debug_strings[2]; logmsgs[1] = (((back->n).h) ? ((back->n).h) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[3]; logmsgs[1] = (((back->d).h) ? ((back->d).h) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[4]; logmsgs[1] = (((back->d).t) ? ((back->d).t) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[20]; logmsgs[1] = (((back->d).etc) ? ((back->d).etc) : unix_sysconfdir); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[14]; logmsgs[1] = (((back->d).pt) ? ((back->d).pt) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[5]; logmsgs[1] = (((back->d).a) ? ((back->d).a) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[6]; logmsgs[1] = (((back->d).s) ? ((back->d).s) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[7]; logmsgs[1] = (((back->x).f) ? ((back->x).f) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[8]; logmsgs[1] = (((back->x).d) ? ((back->x).d) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[9]; logmsgs[1] = (((back->l).f.n) ? ((back->l).f.n) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[10]; logmsgs[1] = (((back->loc).l) ? ((back->loc).l) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[11]; logmsgs[1] = (((back->loc).r) ? ((back->loc).r) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); logmsgs[0] = debug_strings[12]; logmsgs[1] = (((back->loc).e) ? ((back->loc).e) : (debug_strings[13])); dkapp_log_msg(back,DK_LOG_LEVEL_DEBUG,logmsgs,2); } else { my_find_multi(back,debug_string_finder,NULL,0); } $? ". user name: %s", TR_STR((back->n).u) $? ". application name: %s", TR_STR((back->n).a) $? ". host name: %s", TR_STR((back->n).h) $? ". home directory %s", TR_STR((back->d).h) $? ". temp directory %s", TR_STR((back->d).t) $? ". proc temp dir %s", TR_STR((back->d).pt) $? ". application directory %s", TR_STR((back->d).a) $? ". shared directory %s", TR_STR((back->d).s) $? ". executable file %s", TR_STR((back->x).f) $? ". from directory %s", TR_STR((back->x).d) #if DK_HAVE_WINREG_H $? ". registry keys %d", (back->p).what #endif $? ". log file %s", TR_STR((back->l).f.n) $? ". language %s", TR_STR((back->loc).l) $? ". region %s", TR_STR((back->loc).r) $? ". encoding %s", TR_STR((back->loc).e) if((back->n).a) { logmsgs[0] = open_and_close_strings[0]; logmsgs[1] = (back->n).a; logmsgs[2] = open_and_close_strings[1]; dkapp_log_msg(back,DK_LOG_LEVEL_PROGRESS,logmsgs,3); } } } if(buffer2) { dk_delete(buffer2); } if(buffer) { if(dkapp_get_pref(back, key_keep_temp, buffer, maxpathlen, 0)) { char *ptr; ptr = dkstr_start(buffer, NULL); if(ptr) { dkstr_chomp(ptr, NULL); if(dkstr_is_bool(buffer)) { if(dkstr_is_on(buffer)) { back->keep_temp_dir = DK_LOG_LEVEL_IGNORE; } else { back->keep_temp_dir = DK_LOG_LEVEL_NONE; } } else { back->keep_temp_dir = dkstr_array_abbr( log_level_strings, ptr, '$', 0 ); if((back->keep_temp_dir) < 0) { back->keep_temp_dir = DK_LOG_LEVEL_NONE; } } } } dk_delete(buffer); } $? "- dkapp_open %s", TR_PTR(back) return back; } dk_app_t * dkapp_open DK_P2(int, argc, char **, argv) { dk_app_t *back = NULL; back = my_app_open(argc, argv, NULL, NULL, 0, 0); return back; } dk_app_t * dkapp_open_ext1 DK_P6(int,argc,char **,argv,char *,grname,char *,etc,int,sil,int,nostd) { dk_app_t *back = NULL; back = my_app_open(argc, argv, grname, etc, sil, nostd); return back; } int dkapp_tmpnam DK_P3(dk_app_t *, a, char *, buffer, size_t, sz) { int back = 0; char number_buffer[16]; if(a && buffer && sz) { if((a->d).pt) { if((strlen((a->d).pt) + 13) < sz) { sprintf(number_buffer, "%08lX", (a->td).l); (a->td).l += 1UL; strcpy(buffer, (a->d).pt); strcat(buffer, fn_sep); strcat(buffer, number_buffer); strcat(buffer, dot_tmp); back = 1; } } if(!back) { if((a->d).t) { if((strlen((a->d).t) + 13) < sz) { sprintf(number_buffer, "%08lX", (a->td).l); (a->td).l += 1UL; strcpy(buffer, (a->d).t); strcat(buffer, fn_sep); strcat(buffer, number_buffer); strcat(buffer, dot_tmp); back = 1; } } } } return back; } void dkapp_unconfigure DK_P1(dk_app_t *,a) { if(a) { (a->p).unc = 1; } } void dkapp_err_traverse_dir DK_P2(dk_app_t *, app, char *, dirname) { char *logmsg[3]; if(app && dirname) { logmsg[0] = app_err_str[0]; logmsg[1] = dirname; logmsg[2] = app_err_str[1]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_stat_failed DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[2]; logmsg[1] = name; logmsg[2] = app_err_str[3]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_cwd DK_P1(dk_app_t *, app) { char *logmsg[3]; if(app) { logmsg[0] = app_err_str[4]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 1); } } void dkapp_err_matchfile DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[8]; logmsg[1] = name; logmsg[2] = app_err_str[9]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_matchdir DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[10]; logmsg[1] = name; logmsg[2] = app_err_str[11]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_fopenr DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[12]; logmsg[1] = name; logmsg[2] = app_err_str[13]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_fopenw DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[14]; logmsg[1] = name; logmsg[2] = app_err_str[15]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } void dkapp_err_fwrite DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[16]; logmsg[1] = name; logmsg[2] = app_err_str[17]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } int dkapp_log_level_in_use DK_P2(dk_app_t *, app, int, loglevel) { int back = 0; if(app) { if(((app->l).o.m) >= loglevel) { back = 1; } if(((app->l).e.m) >= loglevel) { back = 1; } if(((app->l).f.m) >= loglevel) { back = 1; } #if DK_HAVE_SYSLOG if(((app->l).s.m) >= loglevel) { back = 1; } #endif } return back; } void dkapp_err_fread DK_P2(dk_app_t *, app, char *, name) { char *logmsg[3]; if(app && name) { logmsg[0] = app_err_str[18]; logmsg[1] = name; logmsg[2] = app_err_str[19]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, logmsg, 3); } } int dkapp_get_relaxed_fopen_check DK_P1(dk_app_t *,app) { int back = 0; if(app) { back = app->relaxed_fopen_check; } return back; } dk_stream_t * dkapp_stream_openfile DK_P3(dk_app_t *,a,char *,n,char *,m) { dk_stream_t *back = NULL; int ign, reason; if(n && m) { reason = ign = 0; if(a) { ign = a->relaxed_fopen_check; } back = dkstream_openfile(n,m,ign,&reason); if(a && (!back) && reason) { dkapp_err_nowrite(a,n,reason); } } return back; } void dkapp_err_no_zlib_support_for DK_P2(dk_app_t *,a, char *,n) { char *messages[5]; if((a) && (n)) { messages[0] = app_err_str[21]; messages[1] = n; messages[2] = app_err_str[22]; dkapp_log_msg(a, DK_LOG_LEVEL_ERROR, messages, 3); } } void dkapp_err_no_bzlib_support_for DK_P2(dk_app_t *,a, char *,n) { char *messages[5]; if((a) && (n)) { messages[0] = app_err_str[21]; messages[1] = n; messages[2] = app_err_str[23]; dkapp_log_msg(a, DK_LOG_LEVEL_ERROR, messages, 3); } } dk_stream_t * dkapp_stream_opengz DK_P3(dk_app_t *,a,char *,n,char *,m) { dk_stream_t *back = NULL; int ign, reason; if(n && m) { #if DK_HAVE_ZLIB_H reason = ign = 0; if(a) { ign = a->relaxed_fopen_check; } back = dkstream_opengz(n,m,ign,&reason); if(a && (!back) && reason) { dkapp_err_nowrite(a,n,reason); } #else dkapp_err_no_zlib_support_for(a, n); #endif } return back; } dk_stream_t * dkapp_stream_openbz2 DK_P3(dk_app_t *,a,char *,n,char *,m) { dk_stream_t *back = NULL; int ign, reason; if(n && m) { #if DK_HAVE_BZLIB_H reason = ign = 0; if(a) { ign = a->relaxed_fopen_check; } back = dkstream_openbz2(n,m,ign,&reason); if(a && (!back) && reason) { dkapp_err_nowrite(a,n,reason); } #else dkapp_err_no_bzlib_support_for(a, n); #endif } return back; } FILE * dkapp_fopen DK_P3(dk_app_t *,a,char *,n,char *,m) { FILE *back = NULL; int ign, reason; if(n && m) { ign = reason = 0; if(a) { ign = a->relaxed_fopen_check; } back = dksf_msfo(n,m,ign,&reason); if(a && (!back) && reason) { dkapp_err_nowrite(a,n,reason); } } return back; } char * dkapp_get_appname DK_P1(dk_app_t *,a) { char *back = NULL; if(a) { back = (a->n).a; } return back; } void dkapp_set_silent DK_P2(dk_app_t *,a,int,v) { char buffer[32]; size_t maxpathlen; int i; maxpathlen = sizeof(buffer); if(a) { if(v) { (a->l).f.m = DK_LOG_LEVEL_NONE; (a->l).f.k = DK_LOG_LEVEL_NONE; (a->l).e.m = DK_LOG_LEVEL_NONE; (a->l).o.m = DK_LOG_LEVEL_NONE; } else { if(dkapp_get_pref(a,log_file_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).f.m = i; } } if(dkapp_get_pref(a,log_file_keep,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).f.k = i; } } if(dkapp_get_pref(a,log_stdout_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).o.m = i; } } if(dkapp_get_pref(a,log_stderr_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).e.m = i; } } } } else { set_silent = (v ? 1 : 0); } } EXTERN void dkapp_set_nostdio DK_P2(dk_app_t *,a, int,v) { char buffer[32]; size_t maxpathlen; int i; maxpathlen = sizeof(buffer); if(a) { (a->l).nostdio = v; if(v & DK_APP_LOG_NO_STDOUT) { (a->l).o.m = DK_LOG_LEVEL_NONE; } else { if(dkapp_get_pref(a,log_stdout_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).o.m = i; } } } if(v & DK_APP_LOG_NO_STDERR) { (a->l).e.m = DK_LOG_LEVEL_NONE; } else { if(dkapp_get_pref(a,log_stderr_level,buffer,maxpathlen,0)) { i = get_log_level(buffer); if(i >= 0) { (a->l).e.m = i; } } } } } int dkapp_set_groupname DK_P2(dk_app_t *,a,char *,gn) { int back = 0; char *ptr, *cptr; if(a && gn) { ptr = dkstr_dup(gn); if(ptr) { if((a->n).g) { cptr = (a->n).g ; dk_delete(cptr); (a->n).g = NULL; } (a->n).g = ptr; back = 1; } else { dkapp_err_memory(a, sizeof(char), (1+strlen(gn))); } } return back; } void dkapp_err_tcpip DK_P1(dk_app_t *,app) { if(app) dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, &(app_err_str[20]), 1); } void dkapp_err_no_such_file DK_P2(dk_app_t *, app, char *,pat) { char *msgptr[3]; if(app && pat) { msgptr[0] = open_and_close_strings[22]; msgptr[1] = pat; msgptr[2] = open_and_close_strings[23]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, msgptr, 3); } } void dkapp_err_multiple_files DK_P2(dk_app_t *, app, char *,pat) { char *msgptr[3]; if(app && pat) { msgptr[0] = open_and_close_strings[24]; msgptr[1] = pat; msgptr[2] = open_and_close_strings[25]; dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, msgptr, 3); } } void dkapp_set_source_filename DK_P2(dk_app_t *,a,char *,n) { if(a) { (a->l).ef.n = n; } } char * dkapp_get_source_filename DK_P1(dk_app_t *,a) { char *back = NULL; if(a) { back = (a->l).ef.n; } return back; } void dkapp_set_source_lineno DK_P2(dk_app_t *,a,unsigned long,lineno) { if(a) { (a->l).ef.lineno = lineno; } } unsigned long dkapp_get_source_lineno DK_P1(dk_app_t *,a) { unsigned long back = 0UL; if(a) { back = (a->l).ef.lineno; } return back; } unsigned char * dkapp_get_stdout_codepage DK_P1(dk_app_t *,a) { unsigned char *back = NULL; if(a) { back = (a->l).o.c; } return back; } char * dkapp_fne_one DK_P3(dk_app_t *,a,dk_fne_t *,f,char *,p) { char *back = NULL; char *ptr; if(a && f && p) { if(dkfne_next(f)) { ptr = dkfne_get_fullname(f); if(ptr) { back = dkstr_dup(ptr); if(back) { if(dkfne_next(f)) { dk_delete(back); back = NULL; dkapp_err_multiple_files(a,p); } } else { dkapp_err_memory(a,1,strlen(ptr)); } } else { dkapp_err_no_such_file(a,p); } } else { dkapp_err_no_such_file(a,p); } } return back; } char * dkapp_get_str_pref DK_P2(dk_app_t *,app,char *,key) { char *back = NULL; char buffer[256]; $? "+ dkapp_get_str_pref %s %s", TR_PTR(app), TR_STR(key) if(app && key) { if (dkapp_get_pref(app,key,buffer,sizeof(buffer),0)) { back = dkstr_dup(buffer); if(!back) { dkapp_err_memory(app, sizeof(char), (1+strlen(buffer))); } } } $? "- dkapp_get_str_pref %s", TR_STR(back) return back; } int dkapp_get_bool_pref DK_P2(dk_app_t *,app,char *,key) { int back = -1; char buffer[256]; $? "+ dkapp_get_bool_pref %s %s", TR_PTR(app), TR_STR(key) if (app && key) { if (dkapp_get_pref(app,key,buffer,sizeof(buffer),0)) { if (dkstr_is_bool(buffer)) { if (dkstr_is_on(buffer)) { back = 1; } else { back = 0; } } } } $? "- dkapp_get_bool_pref %d", back return back; } void dkapp_set_keep_temp DK_P2(dk_app_t *,app, int,l) { if(app) { app->keep_temp_dir = l; } } unsigned long dkapp_get_ul_pref DK_P2(dk_app_t *,app,char *,key) { unsigned long back = 0UL; unsigned long ul; char buffer[32]; $? "+ dkapp_get_ul_pref %s %s", TR_PTR(app), TR_STR(key) if(dkapp_get_pref(app, key, buffer, sizeof(buffer), 0)) { if(sscanf(buffer, "%lu", &ul) == 1) { back = ul; } } $? "+ dkapp_get_ul_pref %ul", back return back; } /** Message made of 1 part. @param a Application. @param l Log level. @param s Message text. */ static void msg_1 DK_P3(dk_app_t *,a, int,l, char *,s) { char *logmsg[2]; logmsg[0] = s; logmsg[1] = NULL; dkapp_log_msg(a, l, logmsg, 1); } /** Message made of 3 parts. @param a Application. @param l Log level. @param s1 First part. @param s2 Second part. @param s3 Third part. */ static void msg_3 DK_P5(dk_app_t *,a, int,l, char *,s1, char *,s2, char *,s3) { char *logmsg[4]; logmsg[0] = s1; logmsg[1] = s2; logmsg[2] = s3; logmsg[3] = NULL; dkapp_log_msg(a, l, logmsg, 3); } void dkapp_err_not_a_regular_file DK_P2(dk_app_t *, app, char *,pat) { msg_3(app, DK_LOG_LEVEL_ERROR, app_err_str[24], pat, app_err_str[25]); } void dkapp_info_file_does_not_exist DK_P2(dk_app_t *, app, char *,pat) { msg_3(app, DK_LOG_LEVEL_INFO, app_err_str[26], pat, app_err_str[27]); } void dkapp_err_invalid_permissions DK_P2(dk_app_t *, app, char *,pat) { msg_3(app, DK_LOG_LEVEL_ERROR, app_err_str[28], pat, app_err_str[29]); } void dkapp_err_invalid_owner DK_P2(dk_app_t *, app, char *,pat) { msg_3(app, DK_LOG_LEVEL_ERROR, app_err_str[30], pat, app_err_str[31]); } void dkapp_err_not_a_device DK_P2(dk_app_t *, app, char *,pat) { msg_3(app, DK_LOG_LEVEL_ERROR, app_err_str[32], pat, app_err_str[33]); } void dkapp_info_no_openssl_support DK_P1(dk_app_t *, app) { msg_1(app, DK_LOG_LEVEL_INFO, app_err_str[34]); } void dkapp_debug_attempt_seed_openssl DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[21]); } void dkapp_debug_attempt_seed_random DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[22]); } void dkapp_debug_attempt_seed_rand48 DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[23]); } void dkapp_debug_attempt_seed_rand DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[24]); } void dkapp_debug_failed_seed_openssl DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[25]); } void dkapp_debug_failed_seed_random DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[26]); } void dkapp_debug_failed_seed_rand48 DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[27]); } void dkapp_debug_failed_seed_rand DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[28]); } void dkapp_debug_unavailable_openssl DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[29]); } void dkapp_debug_unavailable_random DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[30]); } void dkapp_debug_unavailable_rand48 DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[31]); } void dkapp_debug_unavailable_rand DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[32]); } void dkapp_debug_attempt_seed_file DK_P2(dk_app_t *,a, char *,fn) { msg_3(a, DK_LOG_LEVEL_DEBUG, debug_strings[33], fn, debug_strings[34]); } void dkapp_debug_attempt_seed_egd DK_P2(dk_app_t *,a, char *,fn) { msg_3(a, DK_LOG_LEVEL_DEBUG, debug_strings[35], fn, debug_strings[36]); } void dkapp_debug_attempt_seed_device DK_P2(dk_app_t *,a, char *,fn) { msg_3(a, DK_LOG_LEVEL_DEBUG, debug_strings[37], fn, debug_strings[38]); } void dkapp_debug_attempt_seed_kbd DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[39]); } void dkapp_debug_attempt_seed_screen DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[40]); } void dkapp_debug_prng_seeded_successfully DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_DEBUG, debug_strings[41]); } void dkapp_warn_prng_not_crypto DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_WARNING, app_err_str[35]); } void dkapp_err_no_prng_found DK_P1(dk_app_t *,a) { msg_1(a, DK_LOG_LEVEL_WARNING, app_err_str[36]); } /** Write a string to standard error output. @param a Application. @param s String to write. */ static void stderr_1 DK_P2(dk_app_t *,a, char *,s) { #if DK_HAVE_CODEPAGES dkcp_fputs(stderr, (a->l).e.c, s); #else fputs(s, stderr); fputc('\n', stderr); #endif } void dkapp_stderr_msg_need_random_input DK_P1(dk_app_t *,a) { stderr_1(a, app_err_str[37]); } void dkapp_stderr_msg_need_more_random_input DK_P1(dk_app_t *,a) { stderr_1(a, app_err_str[38]); } void dkapp_stderr_msg_echo_not_off DK_P1(dk_app_t *,a) { stderr_1(a, app_err_str[39]); } void dkapp_warn_unknown_prng DK_P2(dk_app_t *,a, char *,prng) { msg_3(a, DK_LOG_LEVEL_WARNING, app_err_str[40], prng, app_err_str[41]); }