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