2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* @(#)$XConsortium: file.c /main/7 1996/05/07 13:59:24 drk $ */
30 static void put_selection_entry(/* fp, ent_type, is_valid, val, val2 */);
31 static void put_ims_conf(/* fp, sel */);
32 static void put_select_mode(/* fp, select_mode */);
33 static void put_selection_header(/* fp */);
34 static void put_selection_sep(/* fp */);
35 static int user_selection_fname(/* buf, buf_len, dpy_specific */);
37 static char *SelectFileFormat = NULL;
38 static bool cmdconf_initialized = False;
44 char path[MAXPATHLEN];
46 /* if (!userEnv.homedir || !Conf.userImsDir) return ErrNoHome; */
47 /* get_user_environ() & read_cmd_conf() must be successfully */
48 /* executed prior to calling this function */
51 expand_string("%S", path, MAXPATHLEN, 0);
52 if (!make_user_dir(path)) {
54 expand_string("%U", path, MAXPATHLEN, 0);
55 if (!make_user_dir(path))
57 expand_string("%S", path, MAXPATHLEN, 0);
58 if (!make_user_dir(path))
62 expand_string("%T", path, MAXPATHLEN, 0);
63 if (!make_user_dir(path)) {
64 /* setErrFile(path); return ErrDirCreate; */ /* ignore */
68 if (OpMode == MODE_START) {
69 ret = init_log_file(Opt.LogPath, True);
70 if (ret != NoError && Opt.LogPath) /* try default log file */
71 ret = init_log_file(NULL, True);
72 if (ret != NoError) /* try alternate log file */
73 ret = init_log_file(ALT_LOGPATH, True);
74 DPR(("Opt.LogPath='%s'\n", Opt.LogPath));
80 int init_log_file(org_path, check_size)
84 char path[MAXPATHLEN];
85 bool log_exists = False;
89 /* check log file */ /* if not writable, ims execution will abort */
90 if (!org_path) org_path = DEFAULT_LOGPATH;
91 expand_string(org_path, path, MAXPATHLEN, 0);
92 log_exists = stat(path, &stb) == 0; /* access(path, F_OK) == 0; */
95 if (access(path, W_OK) == -1
96 || stat(path, &stb) == -1 || !S_ISREG(stb.st_mode))
99 /* rename log file if its size is larger than MAX_LOGSIZE (20 KB) */
100 if (check_size && stb.st_size > MAX_LOGSIZE) {
101 char save_path[MAXPATHLEN], *bp;
102 bp = strcpyx(save_path, path); strcpyx(bp, ".old");
103 if (rename(path, save_path) == 0) {
105 DPR(("init_log_file(): %s renamed.\n", path));
107 DPR(("init_log_file(): rename(to: %s) failed.\n", save_path));
112 if ((fd = creat(path, 0666)) == -1)
117 Opt.LogPath = NEWSTR(path);
121 if (Verbose > 1) perror(path);
123 return ErrFileCreate;
127 int set_errorlog(path)
132 /* if (!path) return; */
133 (void) make_user_dir(dirname(path));
134 fd = open(Opt.LogPath, O_WRONLY|O_CREAT|O_APPEND, 0666);
136 if (dup2(fd, 2) >= 0) {
137 /* LogFp = stderr; */
143 if (Verbose > 1) perror(path);
145 return ErrFileCreate;
151 char buf[MAXPATHLEN];
152 CmdConf *conf = &Conf;
153 char *conf_dir, *path;
155 int line_num, num_alias;
161 LocaleAlias *tmp_alias[MAXIMSENT], *ap;
162 # endif /* old_hpux */
164 conf_dir = DTIMS_CONFDIR;
165 if (!(path = Opt.ConfPath) || !*path) {
166 if (!(path = getenv("DTIMS_STARTCONF")) || !*path) {
167 if ((p = getenv("DTIMS_CONFDIR")) && *p)
169 sprintf(path = buf, "%s/%s", conf_dir, DTIMS_CONFFILE);
172 DPR3(("read_cmd_conf(): path=%s\n", path));
174 if ((fp = fopen(path, "r")) == NULL) {
175 DPR3(("\tcannot open '%s'\n", path));
177 DPR(("cannot open '%s' -- continue with default config\n", path));
185 remote = conf->remote = ALLOC(1, RemoteEnv);
186 remote->disabled = remote->useRemsh = False;
187 remote->timeout = REMOTE_TIMEOUT;
188 remote->passEnv = NULL;
191 start_tag_line(path);
192 while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
194 DPR3(("\t[line=%d] no value for '%s'\n", line_num, lp));
198 if (strncmp(lp, "Ims", 3) == 0) {
200 if (strncmp(p, "ConfigDir", 4) == 0) {
201 RENEWSTR(conf->imsConfDir, valp);
202 } else if (strncmp(p, "AppDefDir", 4) == 0) {
203 RENEWSTR(conf->imsAppDir, valp);
204 } else if (strncmp(p, "LogDir", 4) == 0) {
205 RENEWSTR(conf->imsLogDir, valp);
206 } else if (strncmp(p, "LogFile", 4) == 0) {
207 RENEWSTR(conf->imsLogFile, valp);
208 } else if (strncmp(p, "DirName", 3) == 0) {
209 RENEWSTR(conf->imsDir, valp);
212 } else if (strncmp(lp, "User", 4) == 0) {
214 if (strncmp(p, "ImsDir", 4) == 0) {
215 RENEWSTR(conf->userImsDir, valp);
216 } else if (strncmp(p, "TmpDir", 4) == 0) {
217 RENEWSTR(conf->userTmpDir, valp);
218 } else if (strncmp(p, "AltTmpDir", 3) == 0) {
219 RENEWSTR(conf->userAltDir, valp);
222 } else if (strncmp(lp, "Dt", 2) == 0) {
224 if (!conf->dt) dt = conf->dt = ALLOC(1, DtEnv);
225 if (strncmp(p, "ConfigDir", 4) == 0) {
226 RENEWSTR(dt->confDir, valp);
227 } else if (strncmp(p, "UserDir", 5) == 0) {
228 RENEWSTR(dt->userDir, valp);
229 } else if (strncmp(p, "ResourcePath", 4) == 0) {
230 RENEWSTR(dt->resPath, valp);
233 } else if (strncmp(lp, "ImXmod.", 7) == 0) {
235 if (strncmp(p, "XIM", 3) == 0) {
236 RENEWSTR(conf->xmod[Proto_XIM], valp);
237 } else if (strncmp(p, "Ximp", 4) == 0) {
238 RENEWSTR(conf->xmod[Proto_Ximp], valp);
239 } else if (strncmp(p, "Xsi", 3) == 0) {
240 RENEWSTR(conf->xmod[Proto_Xsi], valp);
242 } else if (strncmp(p, "Xhp", 3) == 0) {
243 RENEWSTR(conf->xmod[Proto_Xhp], valp);
244 # endif /* old_hpux */
245 } else if (strncmp(p, "None", 3) == 0) {
246 RENEWSTR(conf->xmod[Proto_None], valp);
249 } else if (strncmp(lp, "ImAtom.", 7) == 0) {
251 if (strncmp(p, "XIM", 3) == 0) {
252 RENEWSTR(conf->atom[Proto_XIM], valp);
253 } else if (strncmp(p, "Ximp", 4) == 0) {
254 RENEWSTR(conf->atom[Proto_Ximp], valp);
255 } else if (strncmp(p, "Xsi", 3) == 0) {
256 RENEWSTR(conf->atom[Proto_Xsi], valp);
258 } else if (strncmp(p, "Xhp", 3) == 0) {
259 RENEWSTR(conf->atom[Proto_Xhp], valp);
260 # endif /* old_hpux */
261 } else if (strncmp(p, "None", 3) == 0) {
262 RENEWSTR(conf->atom[Proto_None], valp);
265 } else if (strncmp(lp, "Action.", 7) == 0) {
267 if (strncmp(p, "GetRemoteConf", 8) == 0) {
268 RENEWSTR(conf->action[ACT_GETREMCONF], valp);
269 } else if (strncmp(p, "RunRemoteIMs", 8) == 0) {
270 RENEWSTR(conf->action[ACT_RUNREMIMS], valp);
273 } else if (strncmp(lp, "Remote", 6) == 0) {
275 if (strncmp(p, "Disabled", 3) == 0) {
276 remote->disabled = str_to_bool(valp, False);
277 } else if (strncmp(p, "UseRemsh", 4) == 0) {
278 remote->useRemsh = str_to_bool(valp, False);
279 } else if (strncmp(p, "Timeout", 3) == 0) {
281 if (str_to_int(valp, &n) && n >= 0)
283 } else if (strncmp(p, "Environment", 3) == 0) {
284 RENEWSTR(remote->passEnv, valp);
288 } else if (strncmp(lp, "Vue", 3) == 0) {
290 if (!conf->vue) vue = conf->vue = ALLOC(1, VueEnv);
291 if (strncmp(p, "ConfigDir", 4) == 0) {
292 RENEWSTR(vue->confDir, valp);
293 } else if (strncmp(p, "UserDir", 5) == 0) {
294 RENEWSTR(vue->userDir, valp);
295 } else if (strncmp(p, "UseLiteFile", 5) == 0) {
296 RENEWSTR(vue->uselite, valp);
297 } else if (strncmp(p, "LiteResourcePath", 5) == 0) {
298 RENEWSTR(vue->litePath, valp);
299 } else if (strncmp(p, "ResourcePath", 5) == 0) {
300 RENEWSTR(vue->resPath, valp);
303 } else if (strncmp(lp, "LocaleAlias", 6) == 0) {
304 ap = ALLOC(1, LocaleAlias);
305 p = valp; cut_field(valp);
306 ap->name = NEWSTR(p);
307 ap->aliases = NEWSTR(valp);
308 tmp_alias[num_alias++] = ap;
309 } else if (strncmp(lp, "XhpLocales", 3) == 0) {
311 p = strrchr(lp, '.');
312 if (!p) continue; /* invalid */
314 case 'J': idx = XHP_JPN; break;
315 case 'K': idx = XHP_KOR; break;
316 case 'C': idx = XHP_CHS; break;
317 case 'T': idx = XHP_CHT; break;
321 conf->xhp = ALLOC(XHP_LANG_NUM, XhpLocale);
322 else if (conf->xhp[idx].locales) {
323 FREE(conf->xhp[idx].locales);
325 conf->xhp[idx].type = p[1];
326 conf->xhp[idx].locales = NEWSTR(valp);
327 # endif /* old_hpux */
330 DPR(("\t[line=%d] invalid entry '%s'\n", line_num, lp));
337 conf->alias = ALLOC(num_alias + 1, LocaleAlias *);
338 memcpy((void *)conf->alias, (void *)tmp_alias,
339 num_alias*sizeof(LocaleAlias *));
340 conf->alias[num_alias] = (LocaleAlias *)0;
342 # endif /* old_hpux */
344 /* if (remote->disabled) FREE(remote->passEnv); */
347 /* set default value unless set */
348 if (!conf->imsConfDir) conf->imsConfDir = NEWSTR(conf_dir);
349 if (!conf->imsAppDir) conf->imsAppDir = NEWSTR(DTIMS_APPDIR);
350 if (!conf->imsLogDir) conf->imsLogDir = NEWSTR(DTIMS_LOGDIR);
351 if (!conf->imsLogFile) conf->imsLogFile = NEWSTR(DTIMS_LOGFILE);
352 if (!conf->imsDir) conf->imsDir = NEWSTR(DTIMS_IMSDIR);
353 if (!conf->userImsDir) conf->userImsDir = NEWSTR(DTIMS_USRIMSDIR);
354 if (!conf->userTmpDir) conf->userTmpDir = NEWSTR(DTIMS_USRTMPDIR);
355 if (!conf->userAltDir) conf->userAltDir = NEWSTR(DTIMS_USRALTDIR);
356 if (!conf->dt) conf->dt = ALLOC(1, DtEnv);
357 if (!conf->dt->confDir) conf->dt->confDir = NEWSTR(DT_CONFDIR);
358 if (!conf->dt->userDir) conf->dt->userDir = NEWSTR(DT_USERDIR);
360 if (!conf->vue) conf->vue = ALLOC(1, VueEnv);
361 if (!conf->vue->confDir) conf->vue->confDir = NEWSTR(VUE_CONFDIR);
362 if (!conf->vue->userDir) conf->vue->userDir = NEWSTR(VUE_USERDIR);
363 # endif /* old_hpux */
364 if (!conf->xmod[Proto_XIM]) conf->xmod[Proto_XIM] = NEWSTR(IM_XMOD_XIM);
365 if (!conf->xmod[Proto_Ximp]) conf->xmod[Proto_Ximp] = NEWSTR(IM_XMOD_XIMP);
366 if (!conf->xmod[Proto_Xsi]) conf->xmod[Proto_Xsi] = NEWSTR(IM_XMOD_XSI);
367 if (!conf->atom[Proto_XIM]) conf->atom[Proto_XIM] = NEWSTR(IM_ATOM_XIM);
368 if (!conf->atom[Proto_Ximp]) conf->atom[Proto_Ximp] = NEWSTR(IM_ATOM_XIMP);
369 if (!conf->atom[Proto_Xsi]) conf->atom[Proto_Xsi] = NEWSTR(IM_ATOM_XSI);
370 /* default value of {xmod,atom}[Proto_None/Xhp] is NULL */
371 if (!conf->action[ACT_GETREMCONF])
372 conf->action[ACT_GETREMCONF] = NEWSTR(NAME_ACT_GETREMCONF);
373 if (!conf->action[ACT_RUNREMIMS])
374 conf->action[ACT_RUNREMIMS] = NEWSTR(NAME_ACT_RUNREMIMS);
376 cmdconf_initialized = True;
380 int expand_cmd_conf()
382 char **pp[20 + NUM_ACTIONS], *p, buf[BUFSIZ];
384 CmdConf *conf = &Conf;
386 #define CHK_ADD(p) if (strchr(p, '%')) pp[n++] = &(p);
389 if (DebugLvl > 1) { pr_CmdConf(); }
393 CHK_ADD(conf->imsConfDir);
394 CHK_ADD(conf->imsAppDir);
395 CHK_ADD(conf->imsLogDir);
396 CHK_ADD(conf->imsLogFile);
397 CHK_ADD(conf->imsDir);
398 CHK_ADD(conf->userImsDir)
399 CHK_ADD(conf->userTmpDir)
400 CHK_ADD(conf->userAltDir)
401 for (j = 0; j < NUM_ACTIONS; j++) CHK_ADD(conf->action[j])
403 CHK_ADD(conf->dt->confDir)
404 CHK_ADD(conf->dt->userDir)
405 CHK_ADD(conf->dt->resPath)
409 CHK_ADD(conf->vue->confDir)
410 CHK_ADD(conf->vue->userDir)
411 CHK_ADD(conf->vue->uselite)
412 CHK_ADD(conf->vue->resPath)
413 CHK_ADD(conf->vue->litePath)
415 # endif /* old_hpux */
416 /* xmod[] & atom[] must not be expanded, since no ims selected */
417 /* remote->* should be expanded at preparation of remote exec */
421 for (i = j = 0; i < n; i++) {
423 expand_string(*(pp[i]), buf, BUFSIZ, 0);
425 if (strcmp(p, buf)) j++;
428 *(pp[i]) = NEWSTR(buf);
431 DPR(("expand_cmd_conf(): %d / %d entries modified\n", j, n));
437 int read_imsconf(conf, ims_name, ims_fname)
439 char *ims_name, *ims_fname;
442 char path[MAXPATHLEN];
444 int len, n, line_num;
447 if (!ims_fname) ims_fname = ims_name;
448 len = expand_string("%I/", path, MAXPATHLEN, 0);
449 strcpyx(path + len, ims_fname);
451 DPR3(("read_imsconf(%s): path=%s\n", ims_name, path));
454 if ((fp = fopen(path, "r")) == NULL) {
455 DPR3(("\tcannot open '%s'\n", path));
459 start_tag_line(path);
460 while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
462 DPR3(("\t[line=%d] no value for '%s'\n", line_num, lp));
465 /* valp = trim_line(valp); */
468 if (strcmp(lp, "name") == 0)
469 ; /* conf->name = NEWSTR(valp); */
470 else if (strcmp(lp, "server_name") == 0) {
471 if (p = strchr(valp, ',')) { /* contain secondary names */
472 conf->servername2 = NEWSTR(valp); /* save full name */
475 conf->servername = NEWSTR(valp); /* save primary name only */
476 } else if (strcmp(lp, "class_name") == 0)
477 conf->classname = NEWSTR(valp);
478 else if (strcmp(lp, "property") == 0)
479 conf->property = NEWSTR(valp);
481 else if (strcmp(lp, "cmd_path") == 0)
482 conf->cmd_path = NEWSTR(valp);
484 else if (strcmp(lp, "cmd_param") == 0)
485 conf->cmd_param = NEWSTR(valp);
488 else if (strcmp(lp, "chk_timeout") == 0) {
489 if (str_to_int(valp, &n))
491 } else if (strcmp(lp, "chk_interval") == 0) {
492 if (str_to_int(valp, &n))
497 #define SET_FLAG(f) \
498 (str_to_bool(valp, False) ? (conf->flags |= (f)) : (conf->flags &= ~(f)))
500 else if (strcmp(lp, "no_server") == 0)
501 SET_FLAG(F_NO_SERVER);
502 else if (strcmp(lp, "no_remote") == 0)
503 SET_FLAG(F_NO_REMOTE);
504 else if (strcmp(lp, "no_option") == 0)
505 SET_FLAG(F_NO_OPTION);
507 else if (strcmp(lp, "try_connect") == 0)
508 SET_FLAG(F_TRY_CONNECT);
509 # endif /* old_hpux */
510 else if (strcmp(lp, "has_window") == 0)
511 SET_FLAG(F_HAS_WINDOW);
515 else if (strcmp(lp, "env_set") == 0)
516 conf->env_set = NEWSTR(valp);
517 else if (strcmp(lp, "env_unset") == 0)
518 conf->env_unset = NEWSTR(valp);
519 else if (strcmp(lp, "env_pass") == 0)
520 conf->env_pass = NEWSTR(valp);
521 else if (strcmp(lp, "protocols") == 0)
522 conf->protocols = parse_protolist(valp);
524 DPR3(("\t[line=%d] invalid entry '%s'\n", line_num, lp));
529 ret = check_ims_conf(conf, ims_name);
536 int check_ims_conf(ims, ims_name)
541 char *missing_entry = NULL;
543 if (strcmp(ims_name, NAME_NONE) == 0) return NoError;
545 if ((ims->cmd_path) && strcmp(ims->cmd_path, NAME_BUILTIN) == 0) {
546 ims->flags |= (F_BUILTIN | F_NO_SERVER | F_NO_REMOTE | F_NO_OPTION);
547 ims->flags &= ~F_TRY_CONNECT;
551 /* check indispensable entry */
552 if (!ims->cmd_path && !(ims->flags & F_BUILTIN)) {
553 missing_entry = "cmd_path";
554 DPR(("read_imsconf(%s): no '%s' entry\n", ims_name, missing_entry));
556 if (!ims->servername) {
557 DPR(("read_imsconf(%s): no '%s' entry\n", ims_name, missing_entry));
558 missing_entry = "servername";
560 if (!ims->protocols) {
561 DPR(("read_imsconf(%s): no '%s' entry\n", ims_name, missing_entry));
562 missing_entry = "protocols";
566 setErrArg1(missing_entry);
573 int read_localeconf(list, locale_name)
577 char path[MAXPATHLEN];
578 char *lp, *valp, *pp;
581 int len, line_num, num_ent;
582 ImsEnt *ent, *etmp[MAXIMSENT];
584 UserEnv *uenv = &userEnv;
586 len = expand_string("%I/", path, MAXPATHLEN, 0);
587 if (!locale_name || !*locale_name) {
588 locale_name = uenv->real_locale ? uenv->real_locale : uenv->locale;
590 strcpyx(path + len, locale_name);
592 DPR3(("read_localeconf(%s): path=%s\n", locale_name, path));
595 list->status = NoError;
596 list->default_idx = -1;
597 list->def_selmode = SEL_MODE_NOAUTO;
599 if ((fp = fopen(path, "r")) == NULL) {
600 DPR3(("\tcannot open '%s'\n", path));
601 list->status = ErrNoLocaleConf;
602 return ErrNoLocaleConf;
606 sel_mode = SEL_MODE_NONE;
608 start_tag_line(path);
609 while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
611 if (lp[0] == STR_PREFIX_CHAR) {
613 DPR3(("\t[line=%d] no value for '%s'\n", line_num, lp));
616 if (strncmp(lp + 1, STR_DEFAULTIMS, 3) == 0) {
617 RENEWSTR(def_name, valp);
618 } else if (strncmp(lp + 1, STR_SELECTMODE, 3) == 0) {
619 int m = SEL_MODE_NONE;
620 if (str_to_int(valp, &m) && m >= 0)
623 DPR2(("\t[line=%d] invalid entry '%s'\n", line_num, lp));
625 } else { /* ims name entry */
626 if (num_ent >= MAXIMSENT) {
627 DPR(("\ttoo many IMS defined: '%s' ignored\n", lp));
630 ent = ALLOC(1, ImsEnt);
631 if (pp = strchr(lp, STR_PREFIX_CHAR)) {
634 ent->fname = NEWSTR(pp);
636 DPR(("\tempty file name for '%s' -- ignored\n", lp));
639 ent->name = NEWSTR(lp);
640 if (valp) ent->label = NEWSTR(valp);
641 etmp[num_ent++] = ent;
647 list->num_ent = num_ent;
648 list->elist = ALLOC(num_ent, ImsEnt *);
649 memcpy((void *)list->elist, (void *)etmp, num_ent*sizeof(ImsEnt *));
652 (sel_mode != SEL_MODE_NONE) ? sel_mode : SEL_MODE_NOAUTO;
656 for (i = 0; i < list->num_ent; i++)
657 if (strcmp(def_name, list->elist[i]->name) == 0) {
658 list->default_idx = i;
666 if (DebugLvl > 2) pr_ImsList(list);
672 int read_user_selection(fselp, locale_name)
676 char path[MAXPATHLEN];
682 dpy_specific = user_selection_fname(path, MAXPATHLEN, -1);
684 DPR3(("read_user_selection(): path=%s\n", path));
686 if ((fp = fopen(path, "r")) == NULL) {
687 DPR3(("\tcannot open '%s'\n", path));
688 /* *fselp = (FileSel *) 0; */
689 return ErrNoSelectionFile;
692 fsel = ALLOC(1, FileSel);
694 start_tag_line(path);
695 ret = read_selection_file(fsel, fp);
698 fsel->dpy_specific = dpy_specific;
699 fsel->real_fname = NEWSTR(locale_name);
705 int read_selection_file(fsel, fp)
709 char *lp, *valp, *vp, *p;
710 int i, nopts, line_num;
711 int select_mode, iconic;
712 char *imsname, *hostname, *com_opt;
713 ImsOpt *opts[MAXIMSENT], *op;
715 select_mode = SEL_MODE_NONE;
716 imsname = hostname = com_opt = NULL;
719 opts[0] = (ImsOpt *)NULL;
721 while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
723 DPR3(("\t[line=%d] no value for '%s'\n", line_num, lp));
726 if (lp[0] != STR_PREFIX_CHAR) {
727 DPR3(("\t[line=%d] invalid name '%s'\n", line_num, lp));
730 if (strncmp(lp + 1, STR_SELECTMODE, 3) == 0) {
731 if (str_to_int(valp, &i) && i >= 0)
733 } else if (strncmp(lp + 1, STR_IMSNAME, 4) == 0) {
734 vp = valp; cut_field(valp);
735 RENEWSTR(imsname, vp);
736 } else if (strncmp(lp + 1, STR_HOSTNAME, 4) == 0) {
737 vp = valp; cut_field(valp);
739 if (strcmp(vp, NAME_LOCAL))
740 hostname = NEWSTR(vp);
741 } else if (strncmp(lp + 1, STR_ICONIC, 3) == 0) {
743 iconic = str_to_bool(valp, False);
744 } else if (strncmp(lp + 1, STR_IMSOPTION, 4) == 0) {
745 if (p = strchr(lp + 1, STR_PREFIX_CHAR)) { /* indiv. opt */
746 if (nopts >= MAXIMSENT) {
747 DPR(("\t[line=%d] too many options - '%s' ignored\n",
752 DPR(("\t[line=%d] no ims name - '%s' ignored\n",
756 for (op = 0, i = 0; i < nopts; i++)
757 if (strcmp(p, opts[i]->ims_name) == 0) {
764 op = ALLOC(1, ImsOpt);
767 op->ims_name = NEWSTR(p);
768 op->opt_str = NEWSTR(valp);
769 } else { /* common opt */
770 RENEWSTR(com_opt, valp);
773 DPR3(("\t[line=%d] unknow name '%s'\n", line_num, lp));
777 fsel->name = imsname;
778 fsel->hostname = hostname;
779 fsel->com_opt = com_opt;
780 fsel->select_mode = select_mode;
781 fsel->iconic = iconic;
784 fsel->opts = ALLOC(nopts + 1, ImsOpt *);
785 COPY(fsel->opts, opts, nopts, ImsOpt *);
786 fsel->opts[nopts] = (ImsOpt *)0;
792 int save_user_selection(sel, locale_name)
796 char path[MAXPATHLEN];
799 FileSel *fsel = sel->fsel;
801 dpy_specific = user_selection_fname(path, MAXPATHLEN, -1);
803 if ((fp = fopen(path, "w")) == NULL) {
804 DPR(("\tcannot create '%s'\n", path));
806 return ErrFileCreate;
809 put_selection_header(fp);
811 put_select_mode(fp, fsel->select_mode);
812 put_ims_conf(fp, sel);
813 put_selection_sep(fp);
816 DPR3(("save_user_selection(): '%s' saved on '%s'\n", sel->name, path));
821 #define _SELECTMODE 0
828 static void put_selection_entry(fp, ent_type, is_valid, val, val2)
837 case _SELECTMODE: name = STR_SELECTMODE; break;
838 case _IMSNAME: name = STR_IMSNAME; break;
839 case _HOSTNAME: name = STR_HOSTNAME; break;
840 case _ICONIC: name = STR_ICONIC; break;
842 case _IMSOPTION: name = STR_IMSOPTION; break;
843 /* default: is_valid = False; */
846 if (!is_valid) putc(COMMENT_CHAR, fp);
847 if (ent_type == _IMSOPT2)
848 fprintf(fp, "%c%s%c%s%c\t%s\n", STR_PREFIX_CHAR, name,
849 STR_PREFIX_CHAR, val2, TAG_END_CHAR, val);
851 fprintf(fp, "%c%s%c\t%s\n", STR_PREFIX_CHAR, name, TAG_END_CHAR, val);
855 static void put_ims_conf(fp, sel)
861 if ((valp = sel->name) && *valp)
862 put_selection_entry(fp, _IMSNAME, True, valp, NULL);
864 DPR(("put_ims_conf(): no ims name\n"));
865 if (sel->fsel && (valp = sel->fsel->name) && *valp)
866 put_selection_entry(fp, _IMSNAME, False, valp, NULL);
868 if ((valp = sel->hostname) && *valp)
869 put_selection_entry(fp, _HOSTNAME, True, valp, NULL);
870 else if (sel->fsel && (valp = sel->fsel->hostname) && *valp)
871 put_selection_entry(fp, _HOSTNAME, False, valp, NULL);
873 if (sel->iconic != -1) {
874 sprintf(val, "%ld", (long)sel->iconic);
875 put_selection_entry(fp, _ICONIC, True, val, NULL);
878 if (sel->fsel && (valp = sel->fsel->com_opt) && *valp) {
879 bool opt_valid = True;
881 opt_valid = !sel->fsel->name || strcmp(sel->name, sel->fsel->name) == 0;
883 put_selection_entry(fp, _IMSOPTION, opt_valid, valp, NULL);
886 if (sel->fsel && sel->fsel->opts) {
888 for (op = sel->fsel->opts; *op; op++)
889 put_selection_entry(fp, _IMSOPT2, True,
890 (*op)->opt_str, (*op)->ims_name);
894 static void put_select_mode(fp, select_mode)
899 if (select_mode != SEL_MODE_NOAUTO && select_mode != SEL_MODE_AUTO
900 #ifdef SelectMode_ONCE
901 && select_mode != SEL_MODE_ONCE
902 #endif /* SelectMode_ONCE */
904 select_mode = SEL_MODE_NOAUTO;
906 sprintf(val, "%ld", (long)select_mode);
907 put_selection_entry(fp, _SELECTMODE, True, val, NULL);
911 static void put_selection_header(fp)
914 fprintf(fp, "%s %s\n", COMMENT_CHARS, ProgramRevision);
915 if (SelectFileFormat)
916 fprintf(fp, "%s%s\n", COMMENT_CHARS, SelectFileFormat);
919 static void put_selection_sep(fp)
922 fprintf(fp, "%s\n", COMMENT_CHARS);
926 int get_select_mode()
928 char path[MAXPATHLEN];
930 int select_mode, dpy_specific;
934 select_mode = SEL_MODE_NONE;
935 dpy_specific = user_selection_fname(path, MAXPATHLEN, -1);
937 DPR3(("get_select_mode(): path=%s\n", path));
939 if ((fp = fopen(path, "r")) == NULL) {
940 DPR3(("\tcannot open '%s'\n", path));
943 start_tag_line(path);
945 while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
946 if (lp[0] == STR_PREFIX_CHAR
947 && strncmp(lp + 1, STR_SELECTMODE, 3) == 0) {
948 if (str_to_int(valp, &n))
954 DPR3(("get_select_mode(%s): select_mode=%d\n",
955 dpy_specific ? "dpy" : NULL, select_mode));
960 int set_select_mode(cur_mode, new_mode)
961 int cur_mode, new_mode;
963 char path[MAXPATHLEN];
968 case SEL_MODE_NOAUTO: break;
969 case SEL_MODE_AUTO: break;
970 #ifdef SelectMode_ONCE
971 case SEL_MODE_ONCE: break;
972 #endif /* SelectMode_ONCE */
974 default: new_mode = SEL_MODE_NOAUTO; break;
977 dpy_specific = user_selection_fname(path, MAXPATHLEN, -1);
979 DPR3(("set_selection_mode(): path=%s\n", path));
982 if (!make_user_dir(dirname(path))) {
983 setErrFile(dirname(path));
988 if ((fp = fopen(path, "r+")) == NULL) {
989 DPR3(("\tcannot open '%s'\n", path));
990 if ((fp = fopen(path, "w")) == NULL) {
992 return ErrFileCreate;
994 cur_mode = SEL_MODE_NONE;
997 if (cur_mode == SEL_MODE_NONE) { /* append '@SelectMode' line */
998 fseek(fp, 0, SEEK_END);
999 put_select_mode(fp, new_mode);
1003 char new_fname[MAXPATHLEN];
1004 char line_buf[BUFSIZ];
1006 int n, line_num, mode_line;
1008 sprintf(new_fname, "%s,tmp", path);
1009 if (!(new_fp = fopen(new_fname, "w"))) {
1011 DPR(("set_select_mode(): cannot create %s\n", new_fname));
1013 return ErrFileCreate;
1016 line_num = mode_line = 0;
1017 while (fgets(lp = line_buf, BUFSIZ, fp)) {
1020 if (*lp == STR_PREFIX_CHAR) {
1021 if (strncmp(lp + 1, STR_SELECTMODE, 3) == 0) {
1022 if (mode_line) continue; /* ignore this line */
1023 if (valp = strchr(lp, TAG_END_CHAR)) {
1026 if (str_to_int(valp, &n) && n == new_mode)
1029 put_select_mode(new_fp, new_mode);
1030 mode_line = line_num;
1032 fputs(line_buf, new_fp);
1034 fputs(line_buf, new_fp);
1037 put_select_mode(new_fp, new_mode);
1041 if (mode_line == -1) { /* not changed */
1042 (void) unlink(new_fname);
1044 if (rename(new_fname, path) == -1) {
1046 return ErrFileCreate;
1049 (void) unlink(new_fname);
1052 DPR2(("set_select_mode(%s): new_mode=%d <- %d\n",
1053 dpy_specific ? "dpy" : NULL, new_mode, cur_mode));
1058 static int user_selection_fname(buf, buf_len, dpy_specific)
1060 int buf_len, dpy_specific;
1063 UserEnv *uenv = &userEnv;
1064 static bool real_done = False;
1067 strncpy(buf, Opt.UserPath, buf_len);
1071 if (dpy_specific == -1) {
1072 len = expand_string("%S/%d", buf, buf_len, 0);
1073 dpy_specific = is_directory(buf, False) ? 1 : 0;
1075 len = expand_string(dpy_specific ? "%S/%d/" : "%S/", buf, buf_len, 0);
1078 if (!real_done && uenv->real_locale) {
1080 strcpy(buf + len, uenv->real_locale);
1081 if (!is_readable(buf, True)) {
1082 bool rename_done = False;
1083 char buf2[MAXPATHLEN], *bp;
1085 strncpy(buf2, buf, len);
1086 bp = buf2 + len; *bp = 0;
1087 if (strcmp(uenv->locale, uenv->real_locale)) {
1088 strcpy(bp, uenv->locale);
1089 if (is_readable(buf2, False)) {
1090 rename_done = rename(buf2, buf) == 0;
1091 DPR(("user_selection_fname(): rename(%s, %s) %s\n",
1092 uenv->locale, uenv->real_locale,
1093 rename_done ? "OK" : "Failed"));
1097 if (uenv->locale_aliases) {
1099 for (ap = uenv->locale_aliases; *ap; ap++) {
1101 if (!is_readable(buf2, False)) continue;
1103 (void) unlink(buf2);
1104 DPR(("user_selection_fname(): unlink(%s) %s\n",
1107 rename_done = rename(buf2, buf) == 0;
1108 DPR(("user_selection_fname(): rename(%s, %s) %s\n",
1109 *ap, uenv->real_locale,
1110 rename_done ? "OK" : "Failed"));
1114 /* real_done = rename_done; */
1117 # endif /* old_hpux */
1119 /* Add the CDE-generic locale name */
1120 strcpy(buf + len, real_done ? uenv->real_locale : uenv->CDE_locale);
1124 return dpy_specific;
1128 int parse_protolist(valp)
1133 if (strstr(valp, "XIM")) proto_bits |= ProtoBit(Proto_XIM);
1134 if (strstr(valp, "Ximp")) proto_bits |= ProtoBit(Proto_Ximp);
1135 if (strstr(valp, "Xsi")) proto_bits |= ProtoBit(Proto_Xsi);
1137 if (strstr(valp, "Xhp")) proto_bits |= ProtoBit(Proto_Xhp);
1138 # endif /* old_hpux */
1139 if (strstr(valp, "None")) proto_bits |= ProtoBit(Proto_None);
1143 int default_protocol(conf)
1146 if (conf->protocols & ProtoBit(Proto_XIM)) return Proto_XIM;
1147 else if (conf->protocols & ProtoBit(Proto_Ximp)) return Proto_Ximp;
1148 else if (conf->protocols & ProtoBit(Proto_Xsi)) return Proto_Xsi;
1150 else if (conf->protocols & ProtoBit(Proto_Xhp)) return Proto_Xhp;
1151 # endif /* old_hpux */
1152 else return Proto_None;