dtimsstart: Change to ANSI function definitions
[oweals/cde.git] / cde / programs / dtimsstart / util.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* @(#)$XConsortium: util.c /main/6 1996/07/12 15:44:21 pascale $ */
24
25 #include <time.h>
26 #include <DtHelp/LocaleXlate.h>  /* for locale equivalence between platforms */
27 #include "xims.h"
28 #include <sys/stat.h>
29
30
31         /* ********  locale name manupilation  ******** */
32
33 int find_CDE_locale_name(void)
34 {
35     UserEnv   *uenv = &userEnv;
36    _DtXlateDb db = NULL;
37    int        ret = NoError;
38    char       plat[_DtPLATFORM_MAX_LEN];
39    int        execver;
40    int        compver;
41    static bool first = True;
42    
43    if (first) {
44
45        uenv->CDE_locale = NULL;
46
47        ret = _DtLcxOpenAllDbs(&db);
48
49        if (ret == NoError)
50            ret = _DtXlateGetXlateEnv(db, plat, &execver, &compver);
51
52        if (ret == NoError)
53            ret = _DtLcxXlateOpToStd(db, plat, compver, DtLCX_OPER_SETLOCALE,
54                                     uenv->locale, &uenv->CDE_locale,
55                                     NULL, NULL, NULL);
56        if (ret == NoError)
57            ret = _DtLcxCloseDb(&db);
58
59        first = False;
60    }
61    return ret;
62 }
63
64 char *find_system_locale_name(char *CDE_locale)
65 {
66    _DtXlateDb db = NULL;
67    int        ret = NoError;
68    char       plat[_DtPLATFORM_MAX_LEN];
69    int        execver;
70    int        compver;
71    char       *locale = NULL;
72
73    ret = _DtLcxOpenAllDbs(&db);
74
75    if (ret == NoError)
76        ret = _DtXlateGetXlateEnv(db, plat, &execver, &compver);
77
78    if (ret == NoError)
79        ret = _DtLcxXlateStdToOp(db, plat, compver, DtLCX_OPER_SETLOCALE,
80                                     CDE_locale, NULL, NULL, NULL,
81                                     &locale);
82    if (ret == NoError)
83        ret = _DtLcxCloseDb(&db);
84
85    if (ret == NoError)
86        return (locale);
87    else
88        return (NULL);
89 }
90
91
92
93         /* ********  string manupilation  ******** */
94
95 char    *strcpyx(register char *dest, register char *src)
96 {
97     while (*dest++ = *src++) ;
98     return(--dest);
99 }
100
101 #ifdef  unused
102 char    *strcpy2(register char *dest, register char *src1, register char *src2)
103 {
104     while (*dest++ = *src1++) ;
105     --dest;
106     while (*dest++ = *src2++) ;
107     return(--dest);
108 }
109
110 char    *newstradded(register char *src1, register char *src2, register char *src3)
111 {
112     register char       *p;
113     char        *dest;
114
115     dest = p = ALLOC(strlen(src1) + strlen(src2) + strlen(src3) + 1, char);
116     if (src1)   { while (*p++ = *src1++) ; p--; }
117     if (src2)   { while (*p++ = *src2++) ; p--; }
118     if (src3)   { while (*p++ = *src3++) ; }
119     return(dest);
120 }
121 #endif  /* unused */
122
123
124 int     str_to_int(char *ptr, int *val)
125 {
126     int base;
127     char *pp;
128
129     /* if (!ptr || !*ptr || !val)       return(False); */
130     *val = 0;
131     base = ptr[0] == '0' ? (((ptr[1] & 0xdf) == 'X') ? 16 : 8) : 10;
132     *val = strtol(ptr, &pp, base);
133     if (!pp || *pp)     return(False);
134     return(True);
135 }
136
137 bool    str_to_bool(char *ptr, bool def_val)
138 {
139     if (!ptr || !*ptr)  return def_val;
140     skip_white(ptr);
141
142     switch (*ptr) {             /* true/false , 0/1 , yes/no , on/off */
143         case '1':
144         case 'T': case 't':
145         case 'Y': case 'y':
146                 def_val = True; break;
147
148         case '0':
149         case 'F': case 'f':
150         case 'N': case 'n':
151                 def_val = False; break;
152
153         case 'O': case 'o':
154                 if (ptr[1] == 'N' || ptr[1] == 'n')
155                     def_val = True;
156                 else if (ptr[1] == 'F' || ptr[1] == 'f')
157                     def_val = False;
158                 break;
159     }
160     return def_val;
161 }
162
163 char    *trim_line(char *ptr)
164 {
165     register char       *lastp;
166
167     skip_white(ptr);
168     for (lastp = ptr + strlen(ptr) - 1;
169         lastp >= ptr && (is_white(*lastp) || *lastp == '\n'); lastp--) ;
170     *(lastp + 1) = 0;
171     return ptr;         /* return lastp > ptr ? ptr : NULL; */
172 }
173
174 char    **parse_strlist(register char *ptr, char sep_ch)
175 {
176     char        *pbuf[100], **new, **bp;
177     char        *sep, *p;
178     int         n;
179     char        *save_ptr;
180
181     if (!ptr || !*ptr)  return (char **)0;
182     ptr = save_ptr = NEWSTR(ptr);
183
184     if (!sep_ch)        sep_ch = ',';
185     bp = pbuf; pbuf[0] = NULL;
186     new = (char **) 0;
187     while (ptr) {
188         if (sep = strchr(ptr, sep_ch))  *sep++ = 0;
189         p = trim_line(ptr);
190         if (*p) {
191             *bp++ = NEWSTR(p);
192             if (bp - pbuf >= 100)       sep = NULL;     /* over-flow */
193         }
194         ptr = sep;
195     }
196     n = bp - pbuf;
197     if (n > 0) {
198         new = ALLOC(n + 1, char *);
199         memcpy((void *) new, (void *)pbuf, n * sizeof(char *));
200         new[n] = NULL;
201     }
202     FREE(save_ptr);
203
204     return new;
205 }
206
207 #ifdef  unused
208 int     pack_strlist(char *ptr, char **listp, char sep_ch)
209 {
210     register char       *bp = ptr, **lp = listp;
211
212     /* if (!ptr)        return 0; */
213     if (!lp || !*lp) {
214         *ptr = 0;
215         return 0;
216     }
217     if (!sep_ch)        sep_ch = ',';
218
219     for (bp; *lp; lp++) {
220         bp = strcpyx(bp, *lp);
221         *bp++ = sep_ch;
222     }
223
224     DPR2(("pack_strlist(): ptr='%s'\n", ptr));
225
226     return bp - ptr;
227 }
228 #endif  /* unused */
229
230 void    free_strlist(char **pp)
231 {
232     register char       **ptr = pp;
233
234     if (!ptr)   return;
235     for ( ; *ptr; ptr++)        FREE(*ptr);
236     FREE(pp);
237 }
238
239
240         /* ********  display string  ******** */
241
242 bool    parse_dpy_str(char *display_str, char **host, int *dnum, int *snum, int *dnet)
243 {
244     char        buf[BUFSIZ], hostbuf[BUFSIZ], *p, *hp, *pdnum, *psnum;
245     int         isdnet = 0;
246
247     snprintf(buf, sizeof(buf), "%s", display_str);
248
249         /* extract host name */
250     if (!(p = strchr(buf, ':')))        return False;
251     *p++ = 0;
252     if (*p == ':') {    /* DECnet ? */
253         *p++ = 0;
254         isdnet = 1;
255     }
256     pdnum = p;
257     hp = buf;
258     if (!*hp || strcmp(hp, "unix") == 0 || strcmp(hp, "local") == 0) {
259         gethostname(hostbuf, BUFSIZ);
260         hp = hostbuf;
261     }
262     if (p = strchr(hp, '.'))    *p = 0;
263
264         /* extract display number */
265     for (p = pdnum; *p && isdigit(*p); p++) ;
266     if (p == pdnum || (*p && *p != '.'))
267         return False;
268
269     psnum = NULL;
270     if (*p) {   /* extract screen number */
271         *p++ = 0;       /* must be '.' */
272         for (psnum = p; *p && isdigit(*p); p++) ;
273         if (p == psnum || *p)   psnum = NULL;
274         *p++ = 0;
275     }
276
277     if (dnum)   *dnum = atoi(pdnum);
278     if (snum)   *snum = psnum ? atoi(psnum) : 0;
279     if (dnet)   *dnet = isdnet ? 1 : 0;
280     if (host)   *host = NEWSTR(hp);
281
282     DPR3(("parse_dpy_str(%s):\thost=%s dnum=%d snum=%d dnet=%d\n",
283                                 display_str, *host, *dnum, *snum, *dnet));
284
285     return True;
286 }
287
288 char    *std_dpy_str(char *display_str, int *snum)
289 {
290     char        buf[BUFSIZ], *bp, val[20];
291     char        *host = NULL;
292     int         dnum = 0, dnet = 0;
293
294     if (snum)   *snum = 0;
295     if (parse_dpy_str(display_str, &host, &dnum, snum, &dnet) == False)
296         return NULL;
297
298     /* sprintf(buf, "%s:%s%d", host, dnet ? ":" : NULL, dnum); */
299     bp = buf; buf[0] = 0;
300     bp = strcpyx(bp, host); *bp++ = ':';
301     if (dnet)   *bp++ = ':';
302     sprintf(val, "%ld", (long) dnum);
303     bp = strcpyx(bp, val);
304
305     DPR3(("std_dpy_str(): \"%s\" --> \"%s\"  snum=%d\n",
306                                         display_str, buf, *snum));
307
308     FREE(host);
309     return NEWSTR(buf);
310 }
311
312
313         /* ********  file & dir manipulation  ******** */
314
315 int     make_user_dir(char *path)
316 {
317     if (!is_directory(path, False)) {
318         if (access(path, F_OK) == 0)
319             return False;
320         if (mkdir(path, 0777) != 0)
321             return False;
322         DPR(("make_user_dir(%s): created\n", path));
323     }
324     return True;
325 }
326
327 char    *dirname(char *path)
328 {
329     static char dname[MAXPATHLEN];
330     register char       *p = path;
331     int         dlen;
332
333     /* if (!p || !p[0])         return NULL; */
334
335     for (p = path + strlen(path) - 1; p > path && *p == '/'; p--) ;
336     dlen = p - path + 1;
337     memcpy(dname, path, dlen);
338     dname[dlen] = 0;
339
340     if (p = strrchr(dname, '/')) {
341         if (p == dname)
342             dname[1] = 0;
343         else {
344             *p = 0;
345             for ( ; p > dname && *p == '/'; p--) *p = 0;
346         }
347     } else
348         strcpy(dname, ".");
349
350     return dname;
351
352 }
353
354 int     is_directory(char *path, int must_writable)
355 {
356     struct stat stb;
357     int         mode = R_OK|X_OK;
358
359     if (must_writable)  mode |= W_OK;
360     return stat(path, &stb) == 0 && S_ISDIR(stb.st_mode)
361                 && access(path, mode) == 0;
362 }
363
364 #ifdef  unused
365 int     is_regularfile(char *path)
366 {
367     struct stat stb;
368     return stat(path, &stb) == 0 && S_ISREG(stb.st_mode);
369 }
370
371 int     is_emptyfile(char *path)
372 {
373     struct stat stb;
374     return stat(path, &stb) == 0 && S_ISREG(stb.st_mode) && stb.st_size == 0;
375 }
376 #endif  /* unused */
377
378
379 int     is_executable(char *path)
380 {
381     struct stat stb;
382     return stat(path, &stb) == 0 && S_ISREG(stb.st_mode)
383                 && access(path, R_OK|X_OK) == 0;
384 }
385
386 #ifdef  unused
387 int     is_writable(char *path)
388 {
389     if (access(path, R_OK|W_OK) == 0)
390         return True;
391     else if (errno == ENOENT)           /* check directory permission */
392         return is_directory(dirname(path), True);
393     else
394         return False;
395 }
396 #endif  /* unused */
397
398 int     is_readable(char *path, int allow_empty)
399 {
400     struct stat stb;
401     return stat(path, &stb) == 0 && S_ISREG(stb.st_mode)
402         && access(path, R_OK) == 0 && (allow_empty || stb.st_size > 0);
403 }
404
405
406         /* ********  file reading  ******** */
407
408 static int      tag_line_num = 0;
409 static char     *tag_linebuf = NULL;
410 static char     *tag_file = NULL;
411
412 int     start_tag_line(char *fname)
413 {
414     if (fname) {
415         if (!tag_linebuf)
416             tag_linebuf = ALLOC(BUFSIZ, char);
417         tag_linebuf[0] = 0;
418         tag_file = fname;
419     } else {
420         if (tag_linebuf)        FREE(tag_linebuf);
421         tag_linebuf = tag_file = 0;
422     }
423     tag_line_num = 0;
424     return True;
425 }
426
427 int     read_tag_line(FILE *fp, char **tagp, char **valp)
428 {
429     char        *lp, *lp2;
430
431     while (fgets(lp = tag_linebuf, BUFSIZ, fp)) {
432         tag_line_num++;
433         skip_white(lp);         /* lp = trim_line(lp); */
434         if (!*lp || *lp == '\n' || is_comment_char(*lp))
435             continue;
436         if (!(lp2 = strchr(lp, TAG_END_CHAR))) {
437             DPR3(("\t[line=%d] no tag on '%s'\n", tag_line_num, tag_file));
438             continue;
439         }
440         *lp2++ = 0;
441         lp2 = trim_line(lp2);
442
443         *tagp = lp;
444         *valp = *lp2 ? lp2 : 0;
445         return tag_line_num;
446     }
447     *tagp = *valp = 0;
448
449     return (ferror(fp)) ? -1 : 0;
450 }
451
452
453         /* ********  put messages  ******** */
454
455 void    put_xims_msg(int msg_type, int err_num, void *arg1, void *arg2, void *arg3)
456 {
457     int         ret = -2;
458     char        *msg;
459
460     msg = xims_errmsg(err_num, arg1, arg2, arg3);
461
462 #if     0
463     {   static char     buf[80];
464         sprintf(buf, "ERROR: %s (%d)\n", error_name(err_num), err_num);
465         msg = buf;
466     }
467 #endif
468
469     if (!msg || !*msg)  return;
470
471     if (UseMsgWindow && useWINDOW()) {
472         ret = put_msg_win(msg_type, msg);
473     }
474
475     if (ret < 0) {
476         fputs(msg, LogFp);
477     }
478
479     LastErrMsg = err_num;
480
481     return;
482 }
483
484 void    put_xims_errmsg(int err_num, void *arg1, void *arg2, void *arg3)
485 {
486     if (Verbose > 0)
487         put_xims_msg(MSGTYP_FATAL, err_num, arg1, arg2, arg3);
488 }
489
490 void    put_xims_warnmsg(int err_num, void *arg1, void *arg2, void *arg3)
491 {
492     if (Verbose > 0)
493         put_xims_msg(MSGTYP_WARN, err_num, arg1, arg2, arg3);
494 }
495
496
497 #ifdef  DEBUG
498     /* for DPR*() macro */
499 void    print_msg(char *fmt, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5)
500 {
501     fprintf(LogFp, fmt, arg1, arg2, arg3, arg4, arg5);
502 }
503 #endif
504
505
506 int     put_xims_log(char *fmt, void *arg1, void *arg2, void *arg3)
507 {
508     FILE        *fp;
509     char        *logpath = Opt.LogPath;
510
511     /* if (Verbose < 1) return False; */
512
513     if (fp = fopen(logpath, "a")) {
514         char    time_str[80];
515         time_t  tm = time((time_t *)0);
516
517         if (strftime(time_str, 80, /* "%x %X" */ "%D %T", localtime(&tm)) == 0)
518             time_str[0] = 0;
519         fprintf(fp, "[%s] %s: ", time_str, ProgramName);
520         fprintf(fp, fmt, arg1, arg2, arg3);
521         putc('\n', fp);
522         fclose(fp);
523         return True;
524     }
525     DPR(("put_xims_log(); failed on '%s'\n", logpath));
526     return False;
527 }
528
529
530         /* ********  clear structure  ******** */
531
532 void    clear_ImsConf(ImsConf *ims)
533 {
534     FREE(ims->servername);
535     FREE(ims->servername2);
536     FREE(ims->classname);
537     FREE(ims->property);
538     FREE(ims->cmd_path);
539     FREE(ims->cmd_param);
540     FREE(ims->env_set);
541     FREE(ims->env_unset);
542     FREE(ims->env_pass);
543
544     CLR(ims, ImsConf);
545 }
546
547 void    clear_ImsEnt(ImsEnt *ent)
548 {
549     FREE(ent->name);
550     FREE(ent->fname);
551     FREE(ent->label);
552     if (ent->ims) {
553         clear_ImsConf(ent->ims);
554         FREE(ent->ims);
555     }
556     CLR(ent, ImsEnt);
557 }
558
559 void    clear_ImsList(ImsList *list)
560 {
561     int         i;
562
563     for (i = 0; i < list->num_ent; i++) {
564         clear_ImsEnt(list->elist[i]);
565         FREE(list->elist[i]);
566     }
567     FREE(list->elist);
568
569     CLR(list, ImsList);
570     list->default_idx = -1;
571     list->def_selmode = SEL_MODE_NOAUTO;
572 }
573
574
575 void    clear_FileSel(FileSel *fsel)
576 {
577     FREE(fsel->name);
578     FREE(fsel->hostname);
579     FREE(fsel->real_fname);
580     FREE(fsel->com_opt);
581     if (fsel->opts) {
582         ImsOpt  **op;
583         for (op = fsel->opts; *op; op++) {
584             FREE((*op)->ims_name);
585             FREE((*op)->opt_str);
586             FREE(*op);
587         }
588         FREE(fsel->opts);
589     }
590
591     CLR(fsel, FileSel);
592
593     fsel->select_mode = SEL_MODE_NONE;
594     fsel->iconic = -1;
595     fsel->dpy_specific = False;
596 }
597
598 void    clear_UserSelection(UserSelection *sel)
599 {
600     FREE(sel->name);
601     FREE(sel->hostname);
602     if (sel->fsel) {
603         clear_FileSel(sel->fsel);
604         FREE(sel->fsel);
605     }
606     if (sel->renv) {
607         clear_RunEnv(sel->renv);
608         FREE(sel->renv);
609     }
610             /* FREE(sel->list); don't free */
611             /* FREE(sel->ent);  don't free */
612
613     CLR(sel, UserSelection);
614
615     sel->host_type = HOST_LOCAL;
616     sel->flag = F_SELECT_NONE;
617     sel->status = NoError;
618     sel->ims_idx = -1;
619     sel->iconic = -1;
620 }
621
622
623 void    clear_RunEnv(RunEnv *renv)
624 {
625     FREE(renv->im_mod);
626     FREE(renv->atom_name);
627     FREE(renv->cmdbuf);
628
629     CLR(renv, RunEnv);
630     renv->status = NoError;;
631 }
632
633
634 void    clear_OutEnv(OutEnv *oenv)
635 {
636     EnvEnt      *ep;
637
638     if (!oenv)  return;
639     if (oenv->set)
640         for (ep = oenv->set; ep->name; ep++) {
641             FREE(ep->name); FREE(ep->value);
642         }
643     if (oenv->unset)
644         for (ep = oenv->unset; ep->name; ep++) {
645             FREE(ep->name); FREE(ep->value);
646         }
647 }
648
649
650 #ifdef  unused
651 void    clear_UserEnv(void)
652 {
653     UserEnv     *uenv = &userEnv;
654
655     FREE(uenv->hostname);
656     FREE(uenv->username);
657     FREE(uenv->homedir);
658     FREE(uenv->locale);
659     FREE(uenv->real_locale);
660     FREE(uenv->displayname);
661     FREE(uenv->displaydir);
662     FREE(uenv->xmodifiers);
663     FREE_LIST(uenv->locale_aliases);
664
665     CLR(&userEnv, UserEnv);
666     return;
667 }
668
669 void    clear_CmdConf(void)
670 {
671     if (cmdconf_initialized) {
672         CmdConf *conf = &Conf;
673         LocaleAlias     **ap;
674         int     i;
675
676         FREE(conf->imsConfDir);
677         FREE(conf->imsAppDir);
678         FREE(conf->imsLogDir);
679         FREE(conf->imsLogDile);
680         FREE(conf->imsDir);
681         FREE(conf->userImsDir);
682         FREE(conf->userTmpDir);
683         FREE(conf->userAltDir);
684
685         for (i = 0; i < NUM_PROTOCOLS; i++) {
686             FREE(conf->xmod[i]);
687             FREE(conf->atom[i]);
688         }
689         for (i = 0; i < NUM_ACTIONS; i++) {
690             FREE(conf->action[i]);
691         }
692         if (conf->remote) {
693             FREE(conf->remote->passEnv);
694             FREE(conf->remote);
695         }
696         if (conf->dt) {
697             FREE(conf->dt->confDir);
698             FREE(conf->dt->userDir);
699             FREE(conf->dt->resPath);
700             FREE(conf->dt);
701         }
702 # ifdef old_hpux
703         if (conf->vue) {
704             FREE(conf->vue->confDir);
705             FREE(conf->vue->userDir);
706             FREE(conf->vue->uselite);
707             FREE(conf->vue->resPath);
708             FREE(conf->vue->litePath);
709             FREE(conf->vue);
710         }       
711         if (conf->alias) {
712             for (ap = conf->alias; *ap; ap++) {
713                 FREE((*ap)->name);
714                 FREE((*ap)->aliases);
715             }
716             FREE(conf->alias);
717         }
718         if (conf->xhp) {
719             for (i = 0; i < XHP_LANG_NUM; i++)
720                 FREE(conf->xhp[i].locales);
721             FREE(conf->xhp);
722         }
723 # endif /* old_hpux */
724     }
725     CLR(&Conf, CmdConf);
726     cmdconf_initialized = False;
727     return;
728 }
729
730 void    clear_WinEnv(void)
731 {
732     CLR(&winEnv, WinEnv);
733 }
734
735 void    clear_CmdOpt(void)
736 {
737     CLR(&Opt, CmdOpt);
738 }
739
740 void    clear_All(void)
741 {
742     UserSelection       *sel = &userSel;
743
744     if (sel->list && sel->list != localList) {
745         clear_ImsList(sel->list);
746         FREE(sel->list);
747     }
748     if (localList) {
749         clear_ImsList(localList);
750         FREE(localList);
751     }
752
753     clear_UserSelection(sel);
754         /* clear_FileSel(sel->fsel); */
755         /* clear_RunEnv(sel->renv); */
756
757     clear_WinEnv();
758     clear_UserEnv();
759     clear_CmdConf();
760     clear_CmdOpt();
761 }
762
763 #endif  /* unused */
764
765
766 #ifdef  DEBUG
767
768         /* ********  print structure (for DEBUG)  ******** */
769
770 void    pr_FileSel(FileSel *fsel)
771 {
772     fprintf(LogFp, "FileSel:\tdpy_specific=%d  real_fname=%s  select_mode=%d\n",
773         fsel->dpy_specific, fsel->real_fname, fsel->select_mode);
774     fprintf(LogFp, "\tname=%s  host=%s  iconic=%d  com_opt='%s'  opts=%#x\n",
775         fsel->name, fsel->hostname, fsel->iconic, fsel->com_opt, fsel->opts);
776
777     if (fsel->opts) {
778         ImsOpt  **op;
779         for (op = fsel->opts; *op; op++)
780             fprintf(LogFp, "\t  opts[%d] <%s>\t'%s'\n",
781                         op - fsel->opts, (*op)->ims_name, (*op)->opt_str);
782     }
783 }
784
785 void    pr_UserSelection(UserSelection *sel)
786 {
787     fprintf(LogFp, "userSelection:\tstatus=%s  flag=%#x  ims_idx=%d\n",
788                         error_name(sel->status), sel->flag, sel->ims_idx);
789     fprintf(LogFp, "\tname=%s  host=%s  host_type=%d  iconic=%d\n",
790                         sel->name, sel->hostname, sel->host_type, sel->iconic);
791     fprintf(LogFp, "\tfsel=%#x  list=%#x  ent=%#x  renv=%#x\n",
792                         sel->fsel, sel->list, sel->ent, sel->renv);
793     if (sel->fsel)      pr_FileSel(sel->fsel);
794     if (sel->renv)      pr_RunEnv(sel->renv);
795 }
796
797 void    pr_ImsConf(ImsConf *conf, char *ims_name)
798 {
799     char        **p;
800
801     fprintf(LogFp, "ImsConf:\tname=%s  protocols=%s%s%s%s\n", ims_name,
802                 (conf->protocols & ProtoBit(Proto_XIM)) ? "XIM,"  : NULL,
803                 (conf->protocols & ProtoBit(Proto_Ximp)) ? "Ximp,"  : NULL,
804                 (conf->protocols & ProtoBit(Proto_Xsi)) ? "Xsi,"  : NULL,
805 # ifdef old_hpux
806                 (conf->protocols & ProtoBit(Proto_Xhp)) ? "Xhp," : NULL,
807 # else
808                 NULL,
809 # endif /* old_hpux */
810                 (conf->protocols & ProtoBit(Proto_None)) ? "None,"  : NULL);
811     fprintf(LogFp, "\tproperty=%s  servername=%s (%s) class=%s\n",
812                 conf->property, conf->servername,
813                 conf->servername2, conf->classname);
814     fprintf(LogFp, "\tpath=%s  param='%s'\n",
815                 conf->cmd_path, conf->cmd_param);
816     fprintf(LogFp, "\ttimeout=%d  interval=%d  flags=%s%s%s\n",
817                 conf->timeout, conf->interval,
818                 (conf->flags & F_NO_SERVER) ? "no_server,"  : NULL,
819                 (conf->flags & F_NO_REMOTE) ? "no_remote,"  : NULL,
820                 (conf->flags & F_NO_OPTION) ? "no_option," : NULL,
821                 (conf->flags & F_TRY_CONNECT) ? "try_connect," : NULL);
822     fprintf(LogFp, "\tenv_set: '%s'\n", conf->env_set);
823     fprintf(LogFp, "\tenv_unset: '%s'\n", conf->env_unset);
824     fprintf(LogFp, "\tenv_pass: '%s'\n", conf->env_pass);
825     fputc('\n', LogFp);
826 }
827
828 void    pr_ImsEnt(ImsEnt *ent, int idx)
829 {
830     fprintf(LogFp, "ImsEnt[%d]:\tname=%s  fname=%s  label=%s  ims=%#x\n",
831                 idx, ent->name, ent->fname, ent->label, ent->ims);
832 }
833
834 void    pr_ImsList(ImsList *list)
835 {
836     int         i;
837     ImsEnt      *ent;
838
839     fprintf(LogFp, "ImsList:\tstatus=%d  num_ent=%d  def_idx=%d  def_sel=%d\n",
840         list->status, list->num_ent, list->default_idx, list->def_selmode);
841     for (i = 0; i < list->num_ent; i++) {
842         ent = list->elist[i];
843         pr_ImsEnt(ent, i);
844         if (ent->ims)   pr_ImsConf(ent->ims, ent->name);
845     }
846 }
847
848 void    pr_WinEnv(WinEnv *wenv)
849 {
850     fprintf(LogFp, "WinEnv:\tstatus=%d  Dpy=%#x  topW=%#x  appC=%#x\n",
851                 wenv->status, wenv->Dpy, wenv->TopW, wenv->appC);
852     fprintf(LogFp, "\tatom_owner=%#x  atom: main=%d status=%d data=%d\n",
853                 wenv->atom_owner, wenv->atom_main, wenv->atom_status, wenv->atom_data);
854 }
855
856 void    pr_RunEnv(RunEnv *renv)
857 {
858     fprintf(LogFp, "RunEnv:\tstatus=%s  is_remote=%d  proto=%d\n",
859                 error_name(renv->status), renv->is_remote, proto_name(renv->proto));
860     fprintf(LogFp, "\tim_mod='%s'  atom_name='%s'  prop_atom=%d\n",
861                 renv->im_mod, renv->atom_name, renv->prop_atom);
862     fprintf(LogFp, "\tpid=%d  wait_status=%#x  cmdbuf='%s'\n",
863                 renv->pid, renv->wait_status, renv->cmdbuf);
864 }
865
866
867 void    pr_UserEnv(void)
868 {
869     UserEnv     *uenv = &userEnv;
870
871     fprintf(LogFp, "UserEnv:\n");
872     fprintf(LogFp, "\thostname=\"%s\"\n", uenv->hostname);
873     fprintf(LogFp, "\tusername=\"%s\"\n", uenv->username);
874     fprintf(LogFp, "\tlocale=\"%s\"  real_locale=\"%s\"\n",
875                                         uenv->locale, uenv->real_locale);
876     fprintf(LogFp, "\thomedir=\"%s\"\n", uenv->homedir);
877     fprintf(LogFp, "\tdisplayname=\"%s\"\n", uenv->displayname);
878     fprintf(LogFp, "\tdisplaydir=\"%s\"\n", uenv->displaydir);
879     fprintf(LogFp, "\tscreen_num=%d\n", uenv->screen_num);
880 }
881
882 void    pr_OutEnv(OutEnv *oenv)
883 {
884     EnvEnt      *ep;
885
886     fprintf(LogFp, "OutEnv:\n");
887     fprintf(LogFp, "  set:  \t");
888     if (oenv->set)
889         for (ep = oenv->set; ep->name; ep++)
890             fprintf(LogFp, "%s='%s' ", ep->name, ep->value);
891     putc('\n', LogFp);
892
893     fprintf(LogFp, "  unset:\t");
894     if (oenv->unset)
895         for (ep = oenv->unset; ep->name; ep++)
896             fprintf(LogFp, "%s='%s' ", ep->name, ep->value);
897     putc('\n', LogFp);
898 }
899
900
901 void    pr_CmdConf(void)
902 {
903     int         i;
904     CmdConf     *conf = &Conf;
905 # ifdef old_hpux
906     LocaleAlias **ap;
907 # endif /* old_hpux */
908     register char       **p;
909
910     fprintf(LogFp, "CmdConf:\n");
911     fprintf(LogFp, "\timsConfDir=%s\n", conf->imsConfDir);
912     fprintf(LogFp, "\timsAppDir=%s\n", conf->imsAppDir);
913     fprintf(LogFp, "\timsLogDir=%s\n", conf->imsLogDir);
914     fprintf(LogFp, "\timsLogFile=%s\n", conf->imsLogFile);
915     fprintf(LogFp, "\timsDir=%s\n", conf->imsDir);
916     fprintf(LogFp, "\tuserImsDir=%s\n", conf->userImsDir);
917     fprintf(LogFp, "\tuserTmpDir=%s\n", conf->userTmpDir);
918     fprintf(LogFp, "\tuserAltDir=%s\n", conf->userAltDir);
919
920 # ifdef old_hpux
921     fprintf(LogFp, "\tImXmod:\tXIM=%s  Ximp=%s  Xsi=%s  Xhp=%s  None=%s\n",
922                 conf->xmod[Proto_XIM], conf->xmod[Proto_Ximp],
923                 conf->xmod[Proto_Xsi], conf->xmod[Proto_Xhp], conf->atom[Proto_None]);
924     fprintf(LogFp, "\tImAtom:\tXIM=%s  Ximp=%s  Xsi=%s  Xhp=%s  None=%s\n",
925                 conf->atom[Proto_XIM], conf->atom[Proto_Ximp],
926                 conf->atom[Proto_Xsi], conf->atom[Proto_Xhp], conf->atom[Proto_None]);
927 # else
928     fprintf(LogFp, "\tImXmod:\tXIM=%s  Ximp=%s  Xsi=%s  None=%s\n",
929                 conf->xmod[Proto_XIM], conf->xmod[Proto_Ximp],
930                 conf->xmod[Proto_Xsi], conf->atom[Proto_None]);
931     fprintf(LogFp, "\tImAtom:\tXIM=%s  Ximp=%s  Xsi=%s  None=%s\n",
932                 conf->atom[Proto_XIM], conf->atom[Proto_Ximp],
933                 conf->atom[Proto_Xsi], conf->atom[Proto_None]);
934 # endif /* old_hpux */
935
936     fprintf(LogFp, "\tAction[%d]:\t{ ", NUM_ACTIONS);
937         for (i = 0; i < NUM_ACTIONS; i++)
938             fprintf(LogFp, "\"%s\", ", conf->action[i]);
939         fprintf(LogFp, "}\n");
940
941     fprintf(LogFp, "\tRemote:\tDisabled=%s  useRemsh=%s  timeout=%d\n",
942                 conf->remote->disabled ? "True" : "False",
943                 conf->remote->useRemsh ? "True" : "False",
944                 conf->remote->timeout);
945     fprintf(LogFp, "\t  Env:\t%s\n", conf->remote->passEnv);
946
947     if (conf->dt) {
948         fprintf(LogFp, "\tDtEnv:\tConfDir=%s  UserDir=%s\n",
949                     conf->dt->confDir, conf->dt->userDir);
950         fprintf(LogFp, "\t  resPath=\"%s\"\n", conf->dt->resPath);
951     } else
952         fprintf(LogFp, "\tDtEnv:\t<None>\n");
953
954 # ifdef old_hpux
955     if (conf->vue) {
956         fprintf(LogFp, "\tVueEnv:\tConfDir=%s  UserDir=%s\n",
957                                 conf->vue->confDir, conf->vue->userDir);
958         fprintf(LogFp, "\t  uselite=%s\n", conf->vue->uselite);
959         fprintf(LogFp, "\t  resPath=\"%s\"\n", conf->vue->resPath);
960         fprintf(LogFp, "\t  litePath=\"%s\"\n", conf->vue->litePath);
961     } else
962         fprintf(LogFp, "\tVueEnv:\t<None>\n");
963
964     fprintf(LogFp, "\tlocaleAlias:\t%s\n", conf->alias ? NULL : "None");
965     if (conf->alias) {
966         for (ap = conf->alias; *ap; ap++)
967             fprintf(LogFp, "\t  [%s]\t%s\n", (*ap)->name, (*ap)->aliases);
968     }
969
970     fprintf(LogFp, "\txhp:\t%s\n", conf->xhp ? NULL : "None");
971     if (conf->xhp) {
972         for (i = 0; i < XHP_LANG_NUM; i++)
973             fprintf(LogFp, "\t  [%c]\t%s\n",
974                                 conf->xhp[i].type, conf->xhp[i].locales);
975     }
976 # endif /* old_hpux */
977 }
978
979 void    pr_CmdOpt(void)
980 {
981     fprintf(LogFp, "CmdOpt:\tDisplayName=%s  LocaleName=%s  ShellName=%s\n",
982                         Opt.DisplayName, Opt.LocaleName, Opt.ShellName);
983     fprintf(LogFp, "\tConfPath=%s  UserPath=%s\n",
984                         Opt.ConfPath, Opt.UserPath);
985     fprintf(LogFp, "\tLogPath=%s  ResourceFile=%s\n",
986                         Opt.LogPath, Opt.ResourceFile);
987     fprintf(LogFp, "\tImsName=%s  HostName=%s  ImsOption=%s\n",
988                         Opt.ImsName, Opt.HostName, Opt.ImsOption);
989     fprintf(LogFp, "\tSelectMode=%d  Timeout=%d  Interval=%d\n",
990                         Opt.SelectMode, Opt.Timeout, Opt.Interval);
991 }
992
993 void    pr_OpModeFlag(void)
994 {
995     char        *name = "<unknown>";
996
997     switch (OpMode) {
998         case MODE_START:        name = "START"; break;
999         case MODE_MODE:         name = "MODE"; break;
1000         case MODE_STYLE:        name = "STYLE"; break;
1001         case MODE_LIST:         name = "LIST"; break;
1002         case MODE_CURRENT:      name = "CURRENT"; break;
1003         case MODE_REMCONF:      name = "REMCONF"; break;
1004     }
1005     fprintf(LogFp, "OpMode=%s[%d]  OpFlag=[%#x] ", name, OpMode, OpFlag);
1006
1007     if (OpFlag) {
1008         if (OpFlag & FLAG_ENV)          fputs("Env, ", LogFp);
1009         if (OpFlag & FLAG_NOSAVE)       fputs("NoSave, ", LogFp);
1010         if (OpFlag & FLAG_NOSTART)      fputs("NoStart, ", LogFp);
1011         if (OpFlag & FLAG_NOWAIT)       fputs("NoWait, ", LogFp);
1012         if (OpFlag & FLAG_NOTIMEOUT)    fputs("NoTimeout, ", LogFp);
1013         if (OpFlag & FLAG_NORESOURCE)   fputs("NoResource, ", LogFp);
1014         if (OpFlag & FLAG_NOREMOTE)     fputs("NoRemote, ", LogFp);
1015         if (OpFlag & FLAG_NOTIFY)       fputs("Notify, ", LogFp);
1016         if (OpFlag & FLAG_CONNECT)      fputs("Connect, ", LogFp);
1017         if (OpFlag & FLAG_REMOTERUN)    fputs("RemoteRun, ", LogFp);
1018         if (OpFlag & FLAG_WINDOW)       fputs("Window, ", LogFp);
1019         if (OpFlag & FLAG_DT)           fputs("Dt, ", LogFp);
1020 # ifdef old_hpux
1021         if (OpFlag & FLAG_VUE)          fputs("Vue, ", LogFp);
1022 # endif /* old_hpux */
1023     }
1024     putc('\n', LogFp);
1025 }
1026
1027 static char     *StateNameTbl[] = {
1028     "None",
1029     "Init",
1030     "Init_Err",
1031     "Init_Done",
1032     "Select",
1033     "Select_Err",
1034     "Select_Canceled",
1035     "Select_Done",
1036     "Start",
1037     "Start_Err",
1038     "Start_Done",
1039     "Wait",
1040     "Wait_Err",
1041     "Wait_Done",
1042     "Finish",
1043     "Finish_Err",
1044     "Finish_Defered",
1045     "Finish_Done",
1046     "Mode",
1047     "Mode_Canceled",
1048     "Mode_Done"
1049 };
1050 #define NumStates       (sizeof(StateNameTbl) / sizeof(char *))
1051
1052 char    *StateName(void)
1053 {
1054     return (OpState >= 0 && OpState < NumStates) ?
1055                                 StateNameTbl[OpState] : "<unknown>";
1056 }
1057
1058
1059         /* ********  error name  ******** */
1060
1061 char    *error_name(ximsError error)
1062 {
1063     char        *name = "<unknown>";
1064
1065 # ifdef __STDC__
1066 #define ERR_CASE(err)   case err :      name = #err; break
1067 # else
1068 #define ERR_CASE(err)   case err :      name = "err"; break
1069 # endif /* __STDC__ */
1070
1071     switch (error) {
1072         ERR_CASE(NoError);
1073         ERR_CASE(ErrSyntax);
1074         ERR_CASE(ErrNoHome);
1075         ERR_CASE(ErrNoLocale);
1076         ERR_CASE(ErrNoCDELocale);
1077         ERR_CASE(ErrNoDisplay);
1078         ERR_CASE(ErrDisabled);
1079         ERR_CASE(ErrSignaled);
1080
1081             /* file */
1082         ERR_CASE(ErrFileOpen);
1083         ERR_CASE(ErrFileCreate);
1084         ERR_CASE(ErrDirCreate);
1085         ERR_CASE(ErrMissEntry);
1086
1087             /* Selection */
1088         ERR_CASE(ErrAnotherProg);
1089         ERR_CASE(ErrNoSelectionFile);
1090         ERR_CASE(ErrSaveSelection);
1091         ERR_CASE(ErrNoSelection);
1092         ERR_CASE(ErrNoLocaleConf);
1093         ERR_CASE(ErrNoImsEntry);
1094         ERR_CASE(ErrNoImsConf);
1095         ERR_CASE(ErrNotRegistered);
1096         ERR_CASE(ErrNoExecutable);
1097
1098             /* Start */
1099         ERR_CASE(ErrImsRunning);
1100         ERR_CASE(ErrImsExecution);
1101         ERR_CASE(ErrImsAborted);
1102         ERR_CASE(ErrImsTimeout);
1103         ERR_CASE(ErrUnknownHost);
1104         ERR_CASE(ErrRemoteAction);
1105         ERR_CASE(ErrRemoteData);
1106         ERR_CASE(ErrRemoteNoIms);
1107         ERR_CASE(ErrRemoteMissIms);
1108         ERR_CASE(ErrNoImsstart);
1109         ERR_CASE(ErrRemoteIms);
1110
1111             /* X */
1112         ERR_CASE(ErrOpenDpy);
1113
1114             /* misc */
1115         ERR_CASE(ErrMemory);
1116
1117             /*internal */
1118         ERR_CASE(ErrIsNone);
1119         ERR_CASE(ErrNotRun);
1120         ERR_CASE(ErrImsWaiting);
1121         ERR_CASE(ErrImsWaitDone);
1122         ERR_CASE(ErrImsConnecting);
1123         ERR_CASE(ErrImsConnectDone);
1124         ERR_CASE(ErrInvState);
1125         ERR_CASE(ErrInternal);
1126     }
1127 #undef  ERR_CASE
1128
1129     return name;
1130 }
1131
1132
1133 static char *_proto_names[NUM_PROTOCOLS] =
1134 # ifdef old_hpux
1135                         { "None", "XIM", "Ximp", "Xsi", "Xhp" };
1136 # else
1137                         { "None", "XIM", "Ximp", "Xsi" };
1138 # endif /* old_hpux */
1139
1140 char    *proto_name(int proto_idx)
1141 {
1142     if (proto_idx >= 0 && proto_idx < NUM_PROTOCOLS)
1143         return _proto_names[proto_idx];
1144     else
1145         return NULL;
1146 }
1147
1148 static char     *SigNames[] = {         /* 1 ~ 32 */
1149     "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT,ABRT", "EMT", "FPE",
1150     "KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", "USR1",
1151     "USR2", "CHLD", "PWR", "VTALRM", "PROF", "POLL,IO", "WINCH", "STOP",
1152     "TSTP", "CONT", "TTIN", "TTOU", "URG", "LOST", "(reserved)", "DIL",
1153 };
1154
1155 #define MaxSigNum       (sizeof(SigNames) / sizeof(char *))
1156
1157 char    *sig_name(int sig)
1158 {
1159     return (sig > 0 && sig <= MaxSigNum) ? SigNames[sig - 1] : "<unknown>";
1160 }
1161
1162
1163 void    pr_brk(char *msg)
1164 {
1165     static char *last_brk = 0;
1166     char        *new_brk = (char *) sbrk(0);
1167     long        inc = (long) (new_brk - last_brk);
1168
1169     inc += inc > 0 ? 1023 : -1023;
1170     DPR(("%s: BREAK=%p (Inc=%+d KB)\n", msg, new_brk, inc/1024));
1171
1172     last_brk = new_brk;
1173 }
1174
1175 #endif  /* DEBUG */
1176