OSDN Git Service

branch: yandytex with kpathsea.
[putex/putex.git] / src / texsourc / kpathsea / kpathsea / tex-file.c
1 /* tex-file.c: high-level file searching by format.
2
3    Copyright 1993, 1994, 1995, 1996, 1997, 2007, 2008, 2009, 2010, 2011
4              2012 Karl Berry.
5    Copyright 1998-2005 Olaf Weber.
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public License
18    along with this library; if not, see <http://www.gnu.org/licenses/>.  */
19
20 #include <kpathsea/config.h>
21
22 #include <kpathsea/c-fopen.h>
23 #include <kpathsea/c-pathch.h>
24 #include <stdarg.h>
25 #include <kpathsea/cnf.h>
26 #include <kpathsea/absolute.h>
27 #include <kpathsea/concatn.h>
28 #include <kpathsea/default.h>
29 #include <kpathsea/expand.h>
30 #include <kpathsea/fontmap.h>
31 #include <kpathsea/paths.h>
32 #include <kpathsea/pathsearch.h>
33 #include <kpathsea/tex-file.h>
34 #include <kpathsea/tex-make.h>
35 #include <kpathsea/variable.h>
36 #include <kpathsea/c-ctype.h>
37
38 /* These are not in the structure
39    because it's annoying to initialize lists in C.  */
40 #define GF_ENVS "GFFONTS", GLYPH_ENVS
41 #define PK_ENVS "PKFONTS", "TEXPKS", GLYPH_ENVS
42 #define GLYPH_ENVS "GLYPHFONTS", "TEXFONTS"
43 #define TFM_ENVS "TFMFONTS", "TEXFONTS"
44 #define AFM_ENVS "AFMFONTS", "TEXFONTS"
45 #define BASE_ENVS "MFBASES", "TEXMFINI"
46 #define BIB_ENVS "BIBINPUTS", "TEXBIB"
47 #define BST_ENVS "BSTINPUTS"
48 #define CNF_ENVS "TEXMFCNF"
49 #define DB_ENVS "TEXMFDBS"
50 #define FMT_ENVS "TEXFORMATS", "TEXMFINI"
51 #define FONTMAP_ENVS "TEXFONTMAPS", "TEXFONTS"
52 #define MEM_ENVS "MPMEMS", "TEXMFINI"
53 #define MF_ENVS "MFINPUTS"
54 #define MFPOOL_ENVS "MFPOOL", "TEXMFINI"
55 #define MFT_ENVS "MFTINPUTS"
56 #define MP_ENVS "MPINPUTS"
57 #define MPPOOL_ENVS "MPPOOL", "TEXMFINI"
58 #define MPSUPPORT_ENVS "MPSUPPORT"
59 #define OCP_ENVS "OCPINPUTS"
60 #define OFM_ENVS "OFMFONTS", "TEXFONTS"
61 #define OPL_ENVS "OPLFONTS", "TEXFONTS"
62 #define OTP_ENVS "OTPINPUTS"
63 #define OVF_ENVS "OVFFONTS", "TEXFONTS"
64 #define OVP_ENVS "OVPFONTS", "TEXFONTS"
65 #define PICT_ENVS "TEXPICTS", TEX_ENVS
66 #define TEX_ENVS "TEXINPUTS"
67 #define TEXDOC_ENVS "TEXDOCS"
68 #define TEXPOOL_ENVS "TEXPOOL", "TEXMFINI"
69 #define TEXSOURCE_ENVS "TEXSOURCES"
70 #define TEX_PS_HEADER_ENVS "TEXPSHEADERS", "PSHEADERS"
71 #define TROFF_FONT_ENVS "TRFONTS"
72 #define TYPE1_ENVS "T1FONTS", "T1INPUTS", "TEXFONTS", TEX_PS_HEADER_ENVS
73 #define VF_ENVS "VFFONTS", "TEXFONTS"
74 #define DVIPS_CONFIG_ENVS "TEXCONFIG"
75 #define IST_ENVS "TEXINDEXSTYLE", "INDEXSTYLE"
76 #define TRUETYPE_ENVS "TTFONTS", "TEXFONTS"
77 #define TYPE42_ENVS "T42FONTS", "TEXFONTS"
78 #define WEB2C_ENVS "WEB2C"
79 #define MISCFONTS_ENVS "MISCFONTS", "TEXFONTS"
80 #define WEB_ENVS "WEBINPUTS"
81 #define CWEB_ENVS "CWEBINPUTS"
82 #define ENC_ENVS "ENCFONTS", "TEXFONTS"
83 #define CMAP_ENVS "CMAPFONTS", "TEXFONTS"
84 #define SFD_ENVS "SFDFONTS", "TEXFONTS"
85 #define OPENTYPE_ENVS "OPENTYPEFONTS", "TEXFONTS"
86 #define PDFTEXCONFIG_ENVS "PDFTEXCONFIG"
87 #define LIG_ENVS "LIGFONTS", "TEXFONTS"
88 #define TEXMFSCRIPTS_ENVS "TEXMFSCRIPTS"
89 #define LUA_ENVS "LUAINPUTS"
90 #define FONTFEATURES_ENVS "FONTFEATURES"
91 #define FONTCIDMAPS_ENVS "FONTCIDMAPS"
92 #define MLBIB_ENVS "MLBIBINPUTS", BIB_ENVS
93 #define MLBST_ENVS "MLBSTINPUTS", BST_ENVS
94 #define CLUA_ENVS "CLUAINPUTS"
95 #define RIS_ENVS "RISINPUTS"
96 #define BLTXML_ENVS "BLTXMLINPUTS"
97 \f
98 /* The compiled-in default list, DEFAULT_FONT_SIZES, is intended to be
99    set from the command line (presumably via the Makefile).  */
100
101 #ifndef DEFAULT_FONT_SIZES
102 #define DEFAULT_FONT_SIZES ""
103 #endif
104
105 void
106 kpathsea_init_fallback_resolutions (kpathsea kpse, string envvar)
107 {
108   string size;
109   const_string size_var = ENVVAR (envvar, "TEXSIZES");
110   string size_str = getenv (size_var);
111   unsigned *last_resort_sizes = NULL;
112   unsigned size_count = 0;
113   const_string default_sizes = kpse->fallback_resolutions_string
114                          ? kpse->fallback_resolutions_string
115                          : DEFAULT_FONT_SIZES;
116   string size_list = kpathsea_expand_default (kpse, size_str, default_sizes);
117
118   /* Initialize the list of last-resort sizes.  */
119   for (size = kpathsea_path_element (kpse, size_list); size != NULL;
120        size = kpathsea_path_element (kpse, NULL))
121     {
122       unsigned s;
123       if (! *size) /* Skip empty elements.  */
124         continue;
125
126       s = atoi (size);
127       if (size_count && s < last_resort_sizes[size_count - 1]) {
128     WARNING1 ("kpathsea: last resort size %s not in ascending order; ignored",
129           size);
130       } else {
131         size_count++;
132         XRETALLOC (last_resort_sizes, size_count, unsigned);
133         last_resort_sizes[size_count - 1] = atoi (size);
134       }
135     }
136
137   /* Add a zero to mark the end of the list.  */
138   size_count++;
139   XRETALLOC (last_resort_sizes, size_count, unsigned);
140   last_resort_sizes[size_count - 1] = 0;
141
142   free (size_list);
143
144   kpse->fallback_resolutions = last_resort_sizes;
145 }
146
147 #if defined (KPSE_COMPAT_API)
148 void
149 kpse_init_fallback_resolutions ( string envvar)
150 {
151   kpathsea_init_fallback_resolutions (kpse_def,  envvar);
152 }
153 #endif
154
155 \f
156 /* We should be able to set the program arguments in the same way.  Not
157    to mention the path values themselves.  */
158
159 void
160 kpathsea_set_program_enabled (kpathsea kpse, kpse_file_format_type fmt,
161                               boolean value, kpse_src_type level)
162 {
163   kpse_format_info_type *f = &(kpse->format_info[fmt]);
164   if (level >= f->program_enable_level) {
165     f->program_enabled_p = value;
166     f->program_enable_level = level;
167   }
168 }
169
170
171 #if defined (KPSE_COMPAT_API)
172 void
173 kpse_set_program_enabled (kpse_file_format_type fmt,
174                           boolean value, kpse_src_type level)
175 {
176   kpathsea_set_program_enabled (kpse_def, fmt, value, level);
177 }
178
179 #endif
180
181
182 /* Web2c and kpsewhich have command-line options to set this stuff.  May
183    as well have a common place.  */
184
185 void
186 kpathsea_maketex_option (kpathsea kpse, const_string fmtname, boolean value)
187 {
188   kpse_file_format_type fmt = kpse_last_format;
189
190   /* Trying to match up with the suffix lists unfortunately doesn't work
191      well, since that would require initializing the formats.  */
192   if (FILESTRCASEEQ (fmtname, "pk")) {
193     fmt = kpse_pk_format;
194   } else if (FILESTRCASEEQ (fmtname, "mf")) {
195     fmt = kpse_mf_format;
196   } else if (FILESTRCASEEQ (fmtname, "tex")) {
197     fmt = kpse_tex_format;
198   } else if (FILESTRCASEEQ (fmtname, "tfm")) {
199     fmt = kpse_tfm_format;
200   } else if (FILESTRCASEEQ (fmtname, "fmt")) {
201     fmt = kpse_fmt_format;
202   } else if (FILESTRCASEEQ (fmtname, "ofm")) {
203     fmt = kpse_ofm_format;
204   } else if (FILESTRCASEEQ (fmtname, "ocp")) {
205     fmt = kpse_ocp_format;
206   } else {
207     fprintf (stderr, "\nkpathsea: Unknown mktex format: %s\n", fmtname);
208   }
209
210   if (fmt != kpse_last_format) {
211     kpathsea_set_program_enabled (kpse, fmt, value, kpse_src_cmdline);
212   }
213 }
214
215 #if defined (KPSE_COMPAT_API)
216 void
217 kpse_maketex_option (const_string fmtname,  boolean value)
218 {
219   kpathsea_maketex_option (kpse_def, fmtname,  value);
220 }
221 #endif
222
223 \f
224 /* Macro subroutine for `init_path'.  EXPAND_DEFAULT calls
225    kpse_expand_default on try_path and the present info->path.  */
226 #define EXPAND_DEFAULT(try_path, source_string)                 \
227   if (try_path) {                                               \
228     info->raw_path = try_path;                                  \
229     tmp = info->path;                                           \
230     info->path = kpathsea_expand_default (kpse, try_path, info->path);  \
231     free (tmp);                                                 \
232     info->path_source = source_string;                          \
233   }
234
235 /* Find the final search path to use for the format entry INFO, given
236    the compile-time default (DEFAULT_PATH), and the environment
237    variables to check (the remaining arguments, terminated with NULL).
238    We set the `path' and `path_source' members of INFO.  The
239    `client_path' member must already be set upon entry.  */
240
241 static void
242 init_path (kpathsea kpse, kpse_format_info_type *info,
243            const_string default_path, ...)
244 {
245   string env_name;
246   string env_value = NULL;
247   string var = NULL;
248   string tmp;
249   va_list ap;
250
251   info->default_path = default_path;
252
253   va_start (ap, default_path);
254   /* First envvar that's set to a nonempty value will exit the loop.  If
255      none are set, we want the first cnf entry that matches.  Find the
256      cnf value simultaneously with the envvar value, to avoid having to
257      go through the envvar list twice,
258      that would mean having to create a str_list and use it twice.  */
259   while ((env_name = va_arg (ap, string)) != NULL) {
260     /* Since sh doesn't like envvar names with `.', check PATH_prog
261        as well as PATH.prog.  */
262     if (!var) { /* Try PATH.prog. */
263       string evar = concat3 (env_name, ".", kpse->program_name);
264       env_value = getenv (evar);
265       if (env_value && *env_value) {
266         var = evar;
267       } else { /* Try PATH_prog. */
268         free (evar);
269         evar = concat3 (env_name, "_", kpse->program_name);
270         env_value = getenv (evar);
271         if (env_value && *env_value) {
272           var = evar;
273         } else { /* Try simply PATH.  */
274           free (evar);
275           env_value = getenv (env_name);
276           if (env_value && *env_value) {
277             var = env_name;
278           }
279         }
280       }
281     }
282
283     /* If we are initializing the cnf path, don't try to get any
284        values from the cnf files; that's infinite loop time.  */
285     if (!info->cnf_path && info != &(kpse->format_info[kpse_cnf_format]))
286       info->cnf_path = kpathsea_cnf_get (kpse, env_name);
287
288     if (var && info->cnf_path)
289       break;
290   }
291   va_end (ap);
292
293   /* Expand any extra :'s.  For each level, we replace an extra : with
294      the path at the next lower level.  For example, an extra : in a
295      user-set envvar should be replaced with the path from the cnf file.
296      things are complicated because none of the levels above the very
297      bottom are guaranteed to exist.  */
298
299   /* Assume we can reliably start with the compile-time default.  */
300   info->raw_path = info->default_path;
301   info->path = xstrdup (info->raw_path);
302   info->path_source = "compile-time paths.h";
303
304   EXPAND_DEFAULT (info->cnf_path, "texmf.cnf");
305   EXPAND_DEFAULT (info->client_path, "program config file");
306
307   if (var) {
308     /* Translate `;' in the envvar into `:' if that's our ENV_SEP. */
309     if (IS_ENV_SEP (':')) {
310       string loc;
311       env_value = xstrdup (env_value);  /* Freed below. */
312       for (loc = env_value; *loc; loc++) {
313         if (*loc == ';')
314           *loc = ':';
315       }
316     }
317     EXPAND_DEFAULT (env_value, concat (var, " environment variable"));
318     /* Do not free the copied env_value, because EXPAND_DEFAULT set
319        raw_path to point to it.  If it gets overwritten again, tough.  */
320   }
321
322   EXPAND_DEFAULT (info->override_path, "application override variable");
323   tmp = info->path;
324   info->path = kpathsea_brace_expand (kpse, info->path);
325   free (tmp);
326 }
327
328
329 /* Some file types have more than one suffix, and sometimes it is
330    convenient to modify the list of searched suffixes.  */
331
332 static void
333 kpathsea_set_suffixes_va_list (kpathsea kpse, kpse_file_format_type format,
334                                boolean alternate, va_list ap)
335 {
336   const_string **list;
337   const_string s;
338   int count = 0;
339
340   if (alternate) {
341     list = &(kpse->format_info[format].alt_suffix);
342   } else {
343     list = &(kpse->format_info[format].suffix);
344   }
345
346   while ((s = va_arg (ap, string)) != NULL) {
347     count++;
348     /* This is essentially
349     XRETALLOC (*list, count + 1, const_string);
350        except that MSVC warns without the cast to `void *'.  */
351     *list = (const_string *) xrealloc ((void *) *list,
352                                        (count + 1) * sizeof(const_string));
353     (*list)[count - 1] = s;
354   }
355   (*list)[count] = NULL;
356 }
357
358 void
359 kpathsea_set_suffixes (kpathsea kpse, kpse_file_format_type format,
360   boolean alternate, ...)
361 {
362   va_list ap;
363   va_start (ap, alternate);
364   kpathsea_set_suffixes_va_list (kpse, format, alternate, ap);
365   va_end (ap);
366 }
367
368
369 #if defined (KPSE_COMPAT_API)
370 void
371 kpse_set_suffixes (kpse_file_format_type format,
372                    boolean alternate, ...)
373 {
374   va_list ap;
375   va_start (ap, alternate);
376   kpathsea_set_suffixes_va_list (kpse_def, format, alternate, ap);
377   va_end (ap);
378 }
379 #endif
380
381
382 /* The path spec we are defining, one element of the global array.  */
383 #define FMT_INFO (kpse->format_info[format])
384 /* Call kpse_set_add_suffixes.  */
385 #define SUFFIXES(args) kpathsea_set_suffixes(kpse, format, false, args, NULL)
386 #define ALT_SUFFIXES(args) kpathsea_set_suffixes(kpse, format, true, args, NULL)
387
388 /* Call `init_path', including appending the trailing NULL to the envvar
389    list. Also initialize the fields not needed in setting the path.  */
390 #define INIT_FORMAT(text, default_path, envs) \
391   FMT_INFO.type = text; \
392   init_path (kpse, &FMT_INFO, default_path, envs, NULL);   \
393   envvar_list = concatn_with_spaces (envs, NULL);
394
395
396 /* A few file types allow for runtime generation by an external program.
397    kpse_init_prog may have already initialized it (the `program'
398    member).  Here we allow people to turn it off or on in the config
399    file, by setting the variable whose name is the uppercasified program
400    name to 0 or 1.  */
401
402 static void
403 init_maketex (kpathsea kpse, kpse_file_format_type fmt,
404               const_string dflt_prog, ...)
405 {
406   kpse_format_info_type *f = &(kpse->format_info[fmt]);
407   const_string prog = f->program ? f->program : dflt_prog; /* mktexpk */
408   string PROG = uppercasify (prog);                  /* MKTEXPK */
409   string progval = kpathsea_var_value (kpse, PROG);  /* $ENV/cnf{"MKTEXPK"} */
410   const_string arg;
411   va_list ap;
412
413   /* Doesn't hurt to always set this info.  */
414   f->program = prog;
415
416   /* Set up the argument vector. */
417   f->argc = 0;
418   f->argv = XTALLOC (2, const_string);
419   f->argv[f->argc++] = dflt_prog;
420   va_start (ap, dflt_prog);
421   while ((arg = va_arg (ap, string)) != NULL) {
422     f->argc++;
423     f->argv = (const_string *) xrealloc ((void *) f->argv,
424                                          (f->argc + 1) * sizeof(const_string));
425     f->argv[f->argc - 1] = arg;
426   }
427   va_end (ap);
428   f->argv[f->argc] = NULL;
429
430   if (progval && *progval) {
431     /* This might actually be from an environment variable value, but in
432        that case, we'll have previously set it from kpse_init_prog.  */
433     kpathsea_set_program_enabled (kpse, fmt, *progval == '1',
434                                   kpse_src_client_cnf);
435   }
436
437   free (PROG);
438 }
439
440 /* We need this twice, so ... */
441 #define MKTEXPK_ARGS \
442   "--mfmode","$MAKETEX_MODE",\
443   "--bdpi","$MAKETEX_BASE_DPI",\
444   "--mag","$MAKETEX_MAG",\
445   "--dpi","$KPATHSEA_DPI",\
446   NULL
447
448 static string
449 remove_dbonly (const_string path)
450 {
451   string ret = XTALLOC(strlen (path) + 1, char), q=ret;
452   const_string p=path;
453   boolean new_elt=true;
454
455   while (*p) {
456     if (new_elt && *p && *p == '!' && *(p+1) == '!')
457       p += 2;
458     else {
459       new_elt = (*p == ENV_SEP);
460       *q++ = *p++;
461     }
462   }
463   *q = '\0';
464   return(ret);
465 }
466
467 /* Same as concatn but puts a space between each element.  All this just
468    for nice debugging output.  But it's useful.  */
469
470 static string
471 concatn_with_spaces (const_string str1, ...)
472 {
473   string arg;
474   string ret;
475   va_list ap;
476
477   if (!str1)
478     return NULL;
479
480   ret = xstrdup (str1);
481
482   va_start (ap, str1);
483   while ((arg = va_arg (ap, string)) != NULL)
484     {
485       string temp = concat3 (ret, " ", arg);
486       free (ret);
487       ret = temp;
488     }
489   va_end (ap);
490
491   return ret;
492 }
493
494 \f
495 /* Initialize everything for FORMAT.  */
496
497 const_string
498 kpathsea_init_format (kpathsea kpse, kpse_file_format_type format)
499 {
500   string envvar_list;  /* only for debug output, set in INIT_FORMAT */
501
502   /* If we get called twice, don't redo all the work.  */
503   if (FMT_INFO.path)
504     return FMT_INFO.path;
505
506   switch (format)
507     { /* We might be able to avoid repeating `gf' or whatever so many
508          times with token pasting, but it doesn't seem worth it.  */
509     case kpse_gf_format:
510       INIT_FORMAT ("gf", DEFAULT_GFFONTS, GF_ENVS);
511       SUFFIXES ("gf");
512       FMT_INFO.suffix_search_only = true;
513       FMT_INFO.binmode = true;
514       break;
515     case kpse_pk_format:
516       init_maketex (kpse, format, "mktexpk", MKTEXPK_ARGS);
517       INIT_FORMAT ("pk", DEFAULT_PKFONTS, PK_ENVS);
518       SUFFIXES ("pk");
519       FMT_INFO.suffix_search_only = true;
520       FMT_INFO.binmode = true;
521       break;
522     case kpse_any_glyph_format:
523       init_maketex (kpse, format, "mktexpk", MKTEXPK_ARGS);
524       INIT_FORMAT ("bitmap font", DEFAULT_GLYPHFONTS, GLYPH_ENVS);
525       FMT_INFO.suffix_search_only = true;
526       FMT_INFO.binmode = true;
527       break;
528     case kpse_tfm_format:
529       /* Must come before kpse_ofm_format. */
530       init_maketex (kpse, format, "mktextfm", NULL);
531       INIT_FORMAT ("tfm", DEFAULT_TFMFONTS, TFM_ENVS);
532       SUFFIXES (".tfm");
533       FMT_INFO.suffix_search_only = true;
534       FMT_INFO.binmode = true;
535       break;
536     case kpse_afm_format:
537       INIT_FORMAT ("afm", DEFAULT_AFMFONTS, AFM_ENVS);
538       SUFFIXES (".afm");
539       break;
540     case kpse_base_format:
541       init_maketex (kpse, format, "mktexfmt", NULL);
542       INIT_FORMAT ("base", DEFAULT_MFBASES, BASE_ENVS);
543       SUFFIXES (".base");
544       FMT_INFO.binmode = true;
545       break;
546     case kpse_bib_format:
547       INIT_FORMAT ("bib", DEFAULT_BIBINPUTS, BIB_ENVS);
548       SUFFIXES (".bib");
549       FMT_INFO.suffix_search_only = true;
550       break;
551     case kpse_bst_format:
552       INIT_FORMAT ("bst", DEFAULT_BSTINPUTS, BST_ENVS);
553       SUFFIXES (".bst");
554       break;
555     case kpse_cnf_format:
556       INIT_FORMAT ("cnf", DEFAULT_TEXMFCNF, CNF_ENVS);
557       SUFFIXES (".cnf");
558       break;
559     case kpse_db_format:
560       INIT_FORMAT ("ls-R", DEFAULT_TEXMFDBS, DB_ENVS);
561 #define LSR_SUFFIXES "ls-R", "ls-r"
562       SUFFIXES (LSR_SUFFIXES);
563       FMT_INFO.path = remove_dbonly (FMT_INFO.path);
564       break;
565     case kpse_fmt_format:
566       init_maketex (kpse, format, "mktexfmt", NULL);
567       INIT_FORMAT ("fmt", DEFAULT_TEXFORMATS, FMT_ENVS);
568       SUFFIXES (".fmt");
569       FMT_INFO.binmode = true;
570       break;
571     case kpse_fontmap_format:
572       INIT_FORMAT ("map", DEFAULT_TEXFONTMAPS, FONTMAP_ENVS);
573       SUFFIXES (".map");
574       break;
575     case kpse_mem_format:
576       init_maketex (kpse, format, "mktexfmt", NULL);
577       INIT_FORMAT ("mem", DEFAULT_MPMEMS, MEM_ENVS);
578       SUFFIXES (".mem");
579       FMT_INFO.binmode = true;
580       break;
581     case kpse_mf_format:
582       init_maketex (kpse, format, "mktexmf", NULL);
583       INIT_FORMAT ("mf", DEFAULT_MFINPUTS, MF_ENVS);
584       SUFFIXES (".mf");
585       break;
586     case kpse_mft_format:
587       INIT_FORMAT ("mft", DEFAULT_MFTINPUTS, MFT_ENVS);
588       SUFFIXES (".mft");
589       break;
590     case kpse_mfpool_format:
591       INIT_FORMAT ("mfpool", DEFAULT_MFPOOL, MFPOOL_ENVS);
592       SUFFIXES (".pool");
593       break;
594     case kpse_mp_format:
595       INIT_FORMAT ("mp", DEFAULT_MPINPUTS, MP_ENVS);
596       SUFFIXES (".mp");
597       break;
598     case kpse_mppool_format:
599       INIT_FORMAT ("mppool", DEFAULT_MPPOOL, MPPOOL_ENVS);
600       SUFFIXES (".pool");
601       break;
602     case kpse_mpsupport_format:
603       INIT_FORMAT ("MetaPost support", DEFAULT_MPSUPPORT, MPSUPPORT_ENVS);
604       break;
605     case kpse_ocp_format:
606       init_maketex (kpse, format, "mkocp", NULL);
607       INIT_FORMAT ("ocp", DEFAULT_OCPINPUTS, OCP_ENVS);
608       SUFFIXES (".ocp");
609       FMT_INFO.suffix_search_only = true;
610       FMT_INFO.binmode = true;
611       break;
612     case kpse_ofm_format:
613       init_maketex (kpse, format, "mkofm", NULL);
614       INIT_FORMAT ("ofm", DEFAULT_OFMFONTS, OFM_ENVS);
615 #define OFM_SUFFIXES ".ofm", ".tfm"
616       SUFFIXES (OFM_SUFFIXES);
617       FMT_INFO.suffix_search_only = true;
618       FMT_INFO.binmode = true;
619       break;
620     case kpse_opl_format:
621       INIT_FORMAT ("opl", DEFAULT_OPLFONTS, OPL_ENVS);
622       SUFFIXES (".opl");
623       ALT_SUFFIXES (".pl");
624       FMT_INFO.suffix_search_only = true;
625       break;
626     case kpse_otp_format:
627       INIT_FORMAT ("otp", DEFAULT_OTPINPUTS, OTP_ENVS);
628       SUFFIXES (".otp");
629       FMT_INFO.suffix_search_only = true;
630       break;
631     case kpse_ovf_format:
632       INIT_FORMAT ("ovf", DEFAULT_OVFFONTS, OVF_ENVS);
633 #define OVF_SUFFIXES ".ovf", ".vf"
634       SUFFIXES (OVF_SUFFIXES);
635       FMT_INFO.suffix_search_only = true;
636       FMT_INFO.binmode = true;
637       break;
638     case kpse_ovp_format:
639       INIT_FORMAT ("ovp", DEFAULT_OVPFONTS, OVP_ENVS);
640       SUFFIXES (".ovp");
641       ALT_SUFFIXES (".vpl");
642       FMT_INFO.suffix_search_only = true;
643       break;
644     case kpse_pict_format:
645       INIT_FORMAT ("graphic/figure", DEFAULT_TEXINPUTS, PICT_ENVS);
646 #define ALT_PICT_SUFFIXES ".eps", ".epsi"
647       ALT_SUFFIXES (ALT_PICT_SUFFIXES);
648       FMT_INFO.binmode = true;
649       break;
650     case kpse_tex_format:
651       init_maketex (kpse, format, "mktextex", NULL);
652       INIT_FORMAT ("tex", DEFAULT_TEXINPUTS, TEX_ENVS);
653       SUFFIXES (".tex");
654       /* TeX files can have any obscure suffix in the world (or none at
655          all).  Only check for the most common ones.  */
656 #define ALT_TEX_SUFFIXES ".sty",".cls",".fd",".aux",".bbl",".def",".clo",".ldf"
657       ALT_SUFFIXES (ALT_TEX_SUFFIXES);
658       break;
659     case kpse_tex_ps_header_format:
660       INIT_FORMAT ("PostScript header", DEFAULT_TEXPSHEADERS,
661                    TEX_PS_HEADER_ENVS);
662 /* Unfortunately, at one time dvips used this format for type1 fonts.  */
663 #define ALT_TEXPSHEADER_SUFFIXES ".pro"
664       ALT_SUFFIXES (ALT_TEXPSHEADER_SUFFIXES);
665       FMT_INFO.binmode = true;
666       break;
667     case kpse_texdoc_format:
668       INIT_FORMAT ("TeX system documentation", DEFAULT_TEXDOCS, TEXDOC_ENVS);
669       break;
670     case kpse_texpool_format:
671       INIT_FORMAT ("texpool", DEFAULT_TEXPOOL, TEXPOOL_ENVS);
672       SUFFIXES (".pool");
673       break;
674     case kpse_texsource_format:
675       INIT_FORMAT ("TeX system sources", DEFAULT_TEXSOURCES, TEXSOURCE_ENVS);
676 #define ALT_SOURCES_SUFFIXES ".dtx", ".ins"
677       ALT_SUFFIXES (ALT_SOURCES_SUFFIXES);
678       break;
679     case kpse_troff_font_format:
680       INIT_FORMAT ("Troff fonts", DEFAULT_TRFONTS, TROFF_FONT_ENVS);
681       FMT_INFO.binmode = true;
682       break;
683     case kpse_type1_format:
684       INIT_FORMAT ("type1 fonts", DEFAULT_T1FONTS, TYPE1_ENVS);
685 #define TYPE1_SUFFIXES ".pfa", ".pfb"
686       SUFFIXES (TYPE1_SUFFIXES);
687       FMT_INFO.binmode = true;
688       break;
689     case kpse_vf_format:
690       INIT_FORMAT ("vf", DEFAULT_VFFONTS, VF_ENVS);
691       SUFFIXES (".vf");
692       FMT_INFO.suffix_search_only = true;
693       FMT_INFO.binmode = true;
694       break;
695     case kpse_dvips_config_format:
696       INIT_FORMAT ("dvips config", DEFAULT_TEXCONFIG, DVIPS_CONFIG_ENVS);
697       break;
698     case kpse_ist_format:
699       INIT_FORMAT ("ist", DEFAULT_INDEXSTYLE, IST_ENVS);
700       SUFFIXES (".ist");
701       break;
702     case kpse_truetype_format:
703       INIT_FORMAT ("truetype fonts", DEFAULT_TTFONTS, TRUETYPE_ENVS);
704 #define TRUETYPE_SUFFIXES ".ttf", ".ttc", ".TTF", ".TTC", ".dfont"
705       SUFFIXES (TRUETYPE_SUFFIXES);
706       FMT_INFO.suffix_search_only = false;
707       FMT_INFO.binmode = true;
708       break;
709     case kpse_type42_format:
710       INIT_FORMAT ("type42 fonts", DEFAULT_T42FONTS, TYPE42_ENVS);
711 #define TYPE42_SUFFIXES ".t42", ".T42"
712       SUFFIXES (TYPE42_SUFFIXES);
713       FMT_INFO.binmode = true;
714       break;
715     case kpse_web2c_format:
716       INIT_FORMAT ("web2c files", DEFAULT_WEB2C, WEB2C_ENVS);
717       break;
718     case kpse_program_text_format:
719       INIT_FORMAT ("other text files",
720                    concatn (".", ENV_SEP_STRING, "$TEXMF/",
721                             kpse->program_name, "//", NULL),
722                    concat (uppercasify (kpse->program_name), "INPUTS"));
723       break;
724     case kpse_program_binary_format:
725       INIT_FORMAT ("other binary files",
726                    concatn (".", ENV_SEP_STRING, "$TEXMF/",
727                             kpse->program_name, "//", NULL),
728                    concat (uppercasify (kpse->program_name), "INPUTS"));
729       FMT_INFO.binmode = true;
730       break;
731     case kpse_miscfonts_format:
732       INIT_FORMAT ("misc fonts", DEFAULT_MISCFONTS, MISCFONTS_ENVS);
733       FMT_INFO.binmode = true;
734       break;
735     case kpse_web_format:
736       INIT_FORMAT ("web", DEFAULT_WEBINPUTS, WEB_ENVS);
737       SUFFIXES (".web");
738       ALT_SUFFIXES (".ch");
739       break;
740     case kpse_cweb_format:
741       INIT_FORMAT ("cweb", DEFAULT_CWEBINPUTS, CWEB_ENVS);
742 #define CWEB_SUFFIXES ".w", ".web"
743       SUFFIXES (CWEB_SUFFIXES);
744       ALT_SUFFIXES (".ch");
745       break;
746     case kpse_enc_format:
747       INIT_FORMAT ("enc files", DEFAULT_ENCFONTS, ENC_ENVS);
748       SUFFIXES (".enc");
749       FMT_INFO.suffix_search_only = true;
750       break;
751     case kpse_cmap_format:
752       INIT_FORMAT ("cmap files", DEFAULT_CMAPFONTS, CMAP_ENVS);
753       break;
754     case kpse_sfd_format:
755       INIT_FORMAT ("subfont definition files", DEFAULT_SFDFONTS, SFD_ENVS);
756       SUFFIXES (".sfd");
757       FMT_INFO.suffix_search_only = true;
758       break;
759     case kpse_opentype_format:
760       INIT_FORMAT ("opentype fonts", DEFAULT_OPENTYPEFONTS, OPENTYPE_ENVS);
761       SUFFIXES (".otf");
762       FMT_INFO.suffix_search_only = true;
763       FMT_INFO.binmode = true;
764       break;
765     case kpse_pdftex_config_format:
766       INIT_FORMAT ("pdftex config", DEFAULT_PDFTEXCONFIG, PDFTEXCONFIG_ENVS);
767       break;
768     case kpse_lig_format:
769       INIT_FORMAT ("lig files", DEFAULT_LIGFONTS, LIG_ENVS);
770       SUFFIXES (".lig");
771       FMT_INFO.suffix_search_only = true;
772       break;
773     case kpse_texmfscripts_format:
774       INIT_FORMAT ("texmfscripts", DEFAULT_TEXMFSCRIPTS, TEXMFSCRIPTS_ENVS);
775       break;
776     case kpse_lua_format:
777       INIT_FORMAT ("lua", DEFAULT_LUAINPUTS, LUA_ENVS);
778 #define LUA_SUFFIXES \
779   ".lua", ".luatex", ".luc", ".luctex", ".texlua", ".texluc", ".tlu"
780       SUFFIXES (LUA_SUFFIXES);
781       FMT_INFO.suffix_search_only = true;
782       break;
783     case kpse_fea_format:
784       INIT_FORMAT("font feature files", DEFAULT_FONTFEATURES, FONTFEATURES_ENVS);
785       SUFFIXES (".fea");
786       FMT_INFO.suffix_search_only = true;
787       break;
788     case kpse_cid_format:
789       INIT_FORMAT ("cid maps", DEFAULT_FONTCIDMAPS, FONTCIDMAPS_ENVS);
790 #define CID_SUFFIXES ".cid", ".cidmap"
791       SUFFIXES (CID_SUFFIXES);
792       FMT_INFO.suffix_search_only = true;
793       break;
794     case kpse_mlbib_format:
795       INIT_FORMAT ("mlbib", DEFAULT_MLBIBINPUTS, MLBIB_ENVS);
796 #define MLBIB_SUFFIXES ".mlbib", ".bib"
797       SUFFIXES (MLBIB_SUFFIXES);
798       FMT_INFO.suffix_search_only = true;
799       break;
800     case kpse_mlbst_format:
801       INIT_FORMAT ("mlbst", DEFAULT_MLBSTINPUTS, MLBST_ENVS);
802 #define MLBST_SUFFIXES ".mlbst", ".bst"
803       SUFFIXES (MLBST_SUFFIXES);
804       FMT_INFO.suffix_search_only = true;
805       break;
806     case kpse_clua_format:
807       INIT_FORMAT ("clua", DEFAULT_CLUAINPUTS, CLUA_ENVS);
808 #define CLUA_SUFFIXES ".dll", ".so"
809       SUFFIXES (CLUA_SUFFIXES);
810       FMT_INFO.suffix_search_only = true;
811       break;
812     case kpse_ris_format:
813       INIT_FORMAT ("ris", DEFAULT_RISINPUTS, RIS_ENVS);
814       SUFFIXES (".ris");
815       FMT_INFO.suffix_search_only = true;
816       break;
817     case kpse_bltxml_format:
818       INIT_FORMAT ("bltxml", DEFAULT_BLTXMLINPUTS, BLTXML_ENVS);
819       SUFFIXES (".bltxml");
820       FMT_INFO.suffix_search_only = true;
821       break;
822     default:
823       LIB_FATAL1 ("kpse_init_format: Unknown format %d", format);
824     }
825
826 #ifdef KPSE_DEBUG
827 #define MAYBE(member) (FMT_INFO.member ? FMT_INFO.member : "(none)")
828
829   /* Describe the monster we've created.  */
830   if (KPATHSEA_DEBUG_P (KPSE_DEBUG_PATHS))
831     {
832       DEBUGF2 ("Search path for %s files (from %s)\n",
833               FMT_INFO.type, FMT_INFO.path_source);
834       DEBUGF1 ("  = %s\n", FMT_INFO.path);
835       DEBUGF1 ("  before expansion = %s\n", FMT_INFO.raw_path);
836       DEBUGF1 ("  application override path = %s\n", MAYBE (override_path));
837       DEBUGF1 ("  application config file path = %s\n", MAYBE (client_path));
838       DEBUGF1 ("  texmf.cnf path = %s\n", MAYBE (cnf_path));
839       DEBUGF1 ("  compile-time path = %s\n", MAYBE (default_path));
840       DEBUGF1 ("  environment variables = %s\n", envvar_list);
841       DEBUGF  ("  default suffixes =");
842       if (FMT_INFO.suffix) {
843         const_string *ext;
844         for (ext = FMT_INFO.suffix; ext && *ext; ext++) {
845           fprintf (stderr, " %s", *ext);
846         }
847         putc ('\n', stderr);
848       } else {
849         fputs (" (none)\n", stderr);
850       }
851       DEBUGF  ("  other suffixes =");
852       if (FMT_INFO.alt_suffix) {
853         const_string *alt;
854         for (alt = FMT_INFO.alt_suffix; alt && *alt; alt++) {
855           fprintf (stderr, " %s", *alt);
856         }
857         putc ('\n', stderr);
858       } else {
859         fputs (" (none)\n", stderr);
860       }
861       DEBUGF1 ("  search only with suffix = %d\n",FMT_INFO.suffix_search_only);
862       DEBUGF1 ("  runtime generation program = %s\n", MAYBE (program));
863       DEBUGF  ("  runtime generation command =");
864       if (FMT_INFO.argv) {
865         const_string *arg;
866         for (arg = FMT_INFO.argv; *arg; arg++) {
867           fprintf (stderr, " %s", *arg);
868         }
869         putc ('\n', stderr);
870       } else {
871           fputs(" (none)\n", stderr);
872       }
873       DEBUGF1 ("  program enabled = %d\n", FMT_INFO.program_enabled_p);
874       DEBUGF1 ("  program enable level = %d\n", FMT_INFO.program_enable_level);
875       DEBUGF1 ("  open files in binary mode = %d\n", FMT_INFO.binmode);
876       DEBUGF1 ("  numeric format value = %d\n", format);
877     }
878 #endif /* KPSE_DEBUG */
879
880   return FMT_INFO.path;
881 }
882
883 #if defined (KPSE_COMPAT_API)
884 const_string
885 kpse_init_format (kpse_file_format_type format)
886 {
887   return kpathsea_init_format (kpse_def, format);
888 }
889 #endif
890
891 \f
892 /* These are subroutines called twice when finding file, to construct
893    the list of names to search for.  */
894
895 /* We don't even use fontmaps any more in practice, they were for things
896    like the lcircle10/lcirc10 name change many years ago, but let's keep
897    the support working nonetheless.  */
898
899 static void
900 target_fontmaps (kpathsea kpse, string **target, unsigned *count,
901                  const_string name)
902 {
903   const_string *mapped_names = kpathsea_fontmap_lookup (kpse, name);
904
905   if (mapped_names != NULL) {
906     const_string mapped_name;
907     /* We leak mapped_names and its elements, some of the time.  */
908     while ((mapped_name = *mapped_names++) != NULL) {
909       (*target)[(*count)] = xstrdup (mapped_name);
910       (*count)++;
911       XRETALLOC ((*target), (*count)+1, string);
912     }
913   }
914 }
915
916
917 /* Possibly add NAME (and any fontmap equivalents) to the string list
918    in TARGET, depending on the various other parameters.  */
919
920 static void
921 target_asis_name (kpathsea kpse, string **target, unsigned *count,
922     kpse_file_format_type format,
923     const_string name, boolean use_fontmaps, boolean has_potential_suffix,
924     string has_any_suffix)
925 {
926   (void) has_any_suffix; /* -Wunused */
927   /* Look for the name we've been given, provided non-suffix
928      searches are allowed or the name already includes a suffix. */
929   if (has_potential_suffix || !FMT_INFO.suffix_search_only) {
930     (*target)[(*count)] = xstrdup (name);
931     (*count)++;
932     XRETALLOC ((*target), (*count)+1, string);
933
934     if (use_fontmaps) {
935       target_fontmaps (kpse, target, count, name);
936     }
937   }
938 }
939
940
941 /* Possibly add NAME (and any fontmap equivalents), with any suffixes
942    for this FORMAT appended, to TARGET -- if it doesn't already have one
943    of the potential suffixes for FORMAT.  */
944
945 static void
946 target_suffixed_names (kpathsea kpse, string **target, unsigned *count,
947     kpse_file_format_type format,
948     const_string name, boolean use_fontmaps, boolean has_potential_suffix)
949 {
950   const_string *ext;
951   if (has_potential_suffix || !FMT_INFO.suffix) {
952     return;
953   }
954
955   for (ext = FMT_INFO.suffix; *ext; ext++) {
956     string name_with_suffix = concat (name, *ext);
957     (*target)[(*count)] = name_with_suffix;
958     (*count)++;
959     XRETALLOC ((*target), (*count)+1, string);
960
961     if (use_fontmaps) {
962       target_fontmaps (kpse, target, count, name_with_suffix);
963     }
964   }
965 }
966 \f
967 /* Look up a file NAME of type FORMAT, and the given MUST_EXIST.  This
968    initializes the path spec for FORMAT if it's the first lookup of that
969    type.  Return the filename found, or NULL.  This is the most likely
970    thing for clients to call.  */
971
972 string
973 kpathsea_find_file (kpathsea kpse, const_string name,
974                     kpse_file_format_type format, boolean must_exist)
975 {
976   string *ret_list = kpathsea_find_file_generic (kpse, name, format,
977                                                  must_exist, false);
978   string ret = *ret_list;
979   free (ret_list);
980   return ret;
981 }
982
983 #if defined (KPSE_COMPAT_API)
984 string
985 kpse_find_file (const_string name,  kpse_file_format_type format,
986                 boolean must_exist)
987 {
988   return kpathsea_find_file(kpse_def, name, format, must_exist);
989 }
990 #endif
991
992 /* As with `kpse_find_file', but also allow passing ALL for the search,
993    hence we always return a NULL-terminated list.  */
994
995 string *
996 kpathsea_find_file_generic (kpathsea kpse, const_string const_name,
997                             kpse_file_format_type format,
998                             boolean must_exist, boolean all)
999 {
1000   string *target, name;
1001   const_string *ext;
1002   unsigned count;
1003   unsigned name_len = 0;
1004   boolean has_potential_suffix = false;
1005   string has_any_suffix = NULL;
1006   string try_std_extension_first = NULL;
1007   boolean use_fontmaps = (format == kpse_tfm_format
1008                           || format == kpse_gf_format
1009                           || format == kpse_pk_format
1010                           || format == kpse_ofm_format);
1011   string *ret = NULL;
1012
1013   /* NAME being NULL is a programming bug somewhere.  NAME can be empty,
1014      though; this happens with constructs like `\input\relax'.  */
1015   assert (const_name);
1016
1017   if (FMT_INFO.path == NULL)
1018     kpathsea_init_format (kpse, format);
1019
1020 #ifdef KPSE_DEBUG
1021   if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH))
1022     DEBUGF3 ("kpse_find_file: searching for %s of type %s (from %s)\n",
1023              const_name, FMT_INFO.type, FMT_INFO.path_source);
1024 #endif /* KPSE_DEBUG */
1025
1026   /* Do variable and tilde expansion. */
1027   name = kpathsea_expand (kpse, const_name);
1028
1029   try_std_extension_first
1030     = kpathsea_var_value (kpse, "try_std_extension_first");
1031   has_any_suffix = strrchr (name, '.');
1032   if (has_any_suffix) {
1033     string p = strchr (has_any_suffix, DIR_SEP);
1034     if (p) {
1035       has_any_suffix = NULL;
1036     }
1037   }
1038
1039   /* Does NAME already end in a possible suffix?  */
1040   name_len = strlen (name);
1041   if (FMT_INFO.suffix) {
1042     for (ext = FMT_INFO.suffix; !has_potential_suffix && *ext; ext++) {
1043       unsigned suffix_len = strlen (*ext);
1044       has_potential_suffix = (name_len >= suffix_len
1045           && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
1046     }
1047   }
1048   if (!has_potential_suffix && FMT_INFO.alt_suffix) {
1049     for (ext = FMT_INFO.alt_suffix; !has_potential_suffix && *ext; ext++) {
1050       unsigned suffix_len = strlen (*ext);
1051       has_potential_suffix = (name_len >= suffix_len
1052           && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
1053     }
1054   }
1055
1056   /* Set up list of target names to search for, the order depending on
1057      try_std_extension_first.  */
1058   count = 0;
1059   target = XTALLOC1 (string);
1060
1061   if (has_any_suffix
1062       && (try_std_extension_first == NULL || *try_std_extension_first == 'f'
1063           || *try_std_extension_first == '0')) {
1064     target_asis_name (kpse, &target, &count, format, name, use_fontmaps,
1065                       has_potential_suffix, has_any_suffix);
1066     target_suffixed_names (kpse, &target, &count, format, name, use_fontmaps,
1067                            has_potential_suffix);
1068   } else {
1069     target_suffixed_names (kpse, &target, &count, format, name, use_fontmaps,
1070                            has_potential_suffix);
1071     target_asis_name (kpse, &target, &count, format, name, use_fontmaps,
1072                       has_potential_suffix, has_any_suffix);
1073   }
1074
1075   /* Terminate list. */
1076   target[count] = NULL;
1077
1078   if (try_std_extension_first) {
1079     free (try_std_extension_first);
1080   }
1081
1082   /* Search, trying to minimize disk-pounding.  */
1083   ret = kpathsea_path_search_list_generic (kpse, FMT_INFO.path,
1084                                            target, false, all);
1085
1086   /* Do we need to pound the disk? */
1087   if (! *ret && must_exist) {
1088     for (count = 0; target[count]; count++)
1089       free (target[count]);
1090     count = 0;
1091     /* We look for a subset of the previous set of names, so the
1092        target array is large enough.  In particular, we don't pound
1093        the disk for alternate names from the fontmaps.  */
1094     if (!has_potential_suffix && FMT_INFO.suffix_search_only) {
1095       for (ext = FMT_INFO.suffix; *ext; ext++)
1096         target[count++] = concat (name, *ext);
1097     }
1098     if (has_potential_suffix || !FMT_INFO.suffix_search_only) {
1099       target[count++] = xstrdup (name);
1100     }
1101     target[count] = NULL;
1102     ret = kpathsea_path_search_list_generic (kpse, FMT_INFO.path,
1103                                              target, true, all);
1104   }
1105
1106   /* Free the list we created. */
1107   for (count = 0; target[count]; count++)
1108     free (target[count]);
1109   free (target);
1110
1111   /* If nothing was found, call mktex* to create a missing file.  Since
1112      this returns a single string, morph it into a list.  */
1113   if (! *ret && must_exist) {
1114     ret = XTALLOC (2, string);
1115     ret[0] = kpathsea_make_tex (kpse, format, name);
1116     if (ret[0]) {
1117       ret[1] = NULL;
1118     }
1119   }
1120
1121   free (name);
1122
1123   return ret;
1124 }
1125
1126 #if defined (KPSE_COMPAT_API)
1127 string *
1128 kpse_find_file_generic (const_string name,  kpse_file_format_type format,
1129                         boolean must_exist,  boolean all)
1130 {
1131   return kpathsea_find_file_generic(kpse_def, name, format, must_exist, all);
1132 }
1133 #endif
1134
1135
1136 \f
1137 /* Return true if FNAME is acceptable to open for reading or writing.  */
1138
1139 typedef enum ok_type {
1140     ok_reading,
1141     ok_writing
1142 } ok_type;
1143
1144 static const_string ok_type_name[] = {
1145     "reading from",
1146     "writing to"
1147 };
1148
1149 static boolean
1150 kpathsea_name_ok (kpathsea kpse, const_string fname, const_string check_var,
1151                   const_string default_choice, ok_type action, boolean silent)
1152 {
1153   /* We distinguish three cases:
1154      'a' (any)        allows any file to be opened.
1155      'r' (restricted) means disallowing special file names.
1156      'p' (paranoid)   means being really paranoid: disallowing special file
1157                       names and restricting output files to be in or below
1158                       the working directory or $TEXMFOUTPUT, while input files
1159                       must be below the current directory, $TEXMFOUTPUT, or
1160                       (implicitly) in the system areas.
1161      We default to "paranoid".  The error messages from TeX may be puzzling.
1162      This function contains several return and goto statements, be careful.  */
1163
1164   const_string open_choice = kpathsea_var_value (kpse, check_var);
1165
1166   if (!open_choice)
1167     open_choice = default_choice;
1168
1169   if (*open_choice == 'a' || *open_choice == 'y' || *open_choice == '1')
1170     return true;
1171
1172 #if defined (unix) && !defined (MSDOS)
1173   {
1174     /* Disallow .rhosts, .login, .ssh/, ..somefile, ..somedir/somefile,
1175        etc.  But allow .tex (for base LaTeX).  */
1176     const_string q;
1177     const_string qq = fname;
1178     while ((q = strchr (qq, '.'))) {            /* at each dot */
1179       if ((q == fname || IS_DIR_SEP (*(q - 1))) /* start or / precedes dot? */
1180           && !IS_DIR_SEP (*(q + 1))             /* ok if /./ */
1181           && !(*(q + 1) == '.' && IS_DIR_SEP (*(q + 2))) /* ok  if /../ */
1182           && !STREQ (q, ".tex")) {              /* specially allow .tex */
1183         goto not_ok;
1184       }
1185       qq = q + 1;
1186     }
1187   }
1188 #else
1189   /* Other OSs don't have special names? */
1190 #endif
1191
1192   if (*open_choice == 'r' || *open_choice == 'n' || *open_choice == '0')
1193     return true;
1194
1195   /* Paranoia originally supplied by Charles Karney.  */
1196   if (kpathsea_absolute_p (kpse, fname, false)) {
1197     const_string texmfoutput = kpathsea_var_value (kpse, "TEXMFOUTPUT");
1198     /* Absolute pathname is only OK if TEXMFOUTPUT is set, it's not empty,
1199        fname begins the TEXMFOUTPUT, and is followed by / */
1200     if (!texmfoutput || *texmfoutput == '\0'
1201         || fname != strstr (fname, texmfoutput)
1202         || !IS_DIR_SEP (fname[strlen (texmfoutput)]))
1203       goto not_ok;
1204   }
1205   /* For all pathnames, we disallow "../" at the beginning or "/../"
1206      anywhere.  */
1207   if (fname[0] == '.' && fname[1] == '.' && IS_DIR_SEP(fname[2]))
1208     goto not_ok;
1209   else {
1210     /* Check for "/../".  Since more than one character can be matched
1211        by IS_DIR_SEP, we cannot use "/../" itself. */
1212     const_string dotpair = strstr (fname, "..");
1213     while (dotpair) {
1214       /* If dotpair[2] == DIR_SEP, then dotpair[-1] is well-defined,
1215          because the "../" case was handled above. */
1216       if (IS_DIR_SEP (dotpair[2]) && IS_DIR_SEP (dotpair[-1]))
1217         goto not_ok;
1218       /* Continue after the dotpair. */
1219       dotpair = strstr (dotpair+2, "..");
1220     }
1221   }
1222
1223   /* We passed all tests.  */
1224   return true;
1225
1226  not_ok: /* Some test failed.  */
1227   if (!silent)
1228     fprintf (stderr, "\n%s: Not %s %s (%s = %s).\n",
1229              kpse->invocation_name, ok_type_name[action], fname,
1230              check_var, open_choice);
1231   return false;
1232 }
1233
1234 /* For input default to all. */
1235
1236 boolean
1237 kpathsea_in_name_ok_silent (kpathsea kpse, const_string fname)
1238 {
1239   return kpathsea_name_ok (kpse, fname, "openin_any", "a", ok_reading, true);
1240 }
1241
1242 boolean
1243 kpathsea_in_name_ok (kpathsea kpse, const_string fname)
1244 {
1245   return kpathsea_name_ok (kpse, fname, "openin_any", "a", ok_reading, false);
1246 }
1247
1248
1249 #if defined(WIN32) || defined(__CYGWIN__)
1250 static int
1251 Isspace (char c)
1252 {
1253   return (c == ' ' || c == '\t');
1254 }
1255
1256 static boolean
1257 executable_filep (kpathsea kpse, const_string fname, boolean silent)
1258 {
1259     const_string fn;
1260     string p, q, base;
1261     string *pp;
1262
1263 /*  check openout_any */
1264     p = kpathsea_var_value (kpse, "openout_any");
1265     if (p && *p == 'p') {
1266       free (p);
1267 /* get base name
1268    we cannot use xbasename() for abnormal names.
1269 */
1270       p = strrchr (fname, '/');
1271       if (p)
1272         fn = p + 1;
1273       else
1274         fn = fname;
1275       p = strrchr (fn, '\\');
1276       if (p)
1277         fn = p + 1;
1278       base = xstrdup (fn);
1279 #if defined(__CYGWIN__)
1280       for (p = base; *p; p++)
1281         *p = TOLOWER (*p);
1282       p = base;
1283 #else
1284       p = (char *) strlwr (base);
1285 #endif
1286       for (q = p + strlen (p) - 1;
1287            (q >= p) && ((*q == '.') || (Isspace (*q))); q--) {
1288         *q = '\0'; /* remove trailing '.' , ' ' and '\t' */
1289       }
1290       q = strrchr (p, '.'); /* get extension part */
1291       pp = kpse->suffixlist;
1292       if (pp && q) {
1293         while (*pp) {
1294           if (strchr (fname, ':') || !strcmp (q, *pp)) {
1295             if (!silent)
1296               fprintf (stderr, "\n%s: Forbidden to open for writing\n", fname);
1297             free (base);
1298             return true;
1299           }
1300           pp++;
1301         }
1302       }
1303       free (base);
1304     } else if (p) {
1305       free (p);
1306     }
1307     return false;
1308 }
1309 #endif /* WIN32 || __CYGWIN__ */
1310
1311 static boolean
1312 kpathsea_out_name_ok_1 (kpathsea kpse, const_string fname, boolean silent)
1313 {
1314 #if defined(WIN32) || defined(__CYGWIN__)
1315   /* Output of an executable file is restricted on Windows */
1316   if (executable_filep (kpse, fname, silent))
1317     return false;
1318 #endif /* WIN32 || __CYGWIN__ */
1319   /* For output, default to paranoid. */
1320   return kpathsea_name_ok (kpse, fname, "openout_any", "p", ok_writing,silent);
1321 }
1322
1323 boolean
1324 kpathsea_out_name_ok_silent (kpathsea kpse, const_string fname)
1325 {
1326   return kpathsea_out_name_ok_1 (kpse, fname, true);
1327 }
1328
1329 boolean
1330 kpathsea_out_name_ok (kpathsea kpse, const_string fname)
1331 {
1332   return kpathsea_out_name_ok_1 (kpse, fname, false);
1333 }
1334
1335 #if defined (KPSE_COMPAT_API)
1336 boolean
1337 kpse_in_name_ok (const_string fname)
1338 {
1339   /* For input default to all. */
1340   return kpathsea_in_name_ok (kpse_def, fname);
1341 }
1342
1343 boolean
1344 kpse_out_name_ok (const_string fname)
1345 {
1346   /* For output, default to paranoid. */
1347   return kpathsea_out_name_ok (kpse_def, fname);
1348 }
1349 #endif
1350
1351
1352 \f
1353 /* Open NAME along the search path for TYPE for reading and return the
1354    resulting file, or exit with an error message.  */
1355
1356 FILE *
1357 kpathsea_open_file (kpathsea kpse, const_string name,
1358                     kpse_file_format_type type)
1359 {
1360   string fullname = kpathsea_find_file (kpse, name, type, true);
1361   const_string mode = kpse->format_info[type].binmode
1362                       ? FOPEN_RBIN_MODE
1363                       : FOPEN_R_MODE;
1364   FILE *f = fullname ? fopen (fullname, mode) : NULL;
1365   if (!f) {
1366     if (fullname) {
1367       perror (fullname);
1368       exit (1);
1369     } else {
1370       LIB_FATAL2 ("%s file `%s' not found", kpse->format_info[type].type, name);
1371     }
1372   }
1373
1374   return f;
1375 }
1376
1377 #if defined (KPSE_COMPAT_API)
1378 FILE *
1379 kpse_open_file (const_string name,  kpse_file_format_type type)
1380 {
1381     return kpathsea_open_file(kpse_def, name, type);
1382 }
1383 #endif
1384
1385 \f
1386 /* When using the %&<format> construct, we'd like to use the paths for
1387    that format, rather than those for the name we were called with.
1388    Of course this happens after various initializations have been
1389    performed, so we have this function to force the issue.  Note that
1390    the paths for kpse_cnf_format and kpse_db_format are not cleared.
1391
1392    This function is defined here, and not in progname.c, because it
1393    need format_info, and would cause all of tex-file to be pulled
1394    in by programs that do not need it. */
1395
1396 void
1397 kpathsea_reset_program_name (kpathsea kpse, const_string progname)
1398 {
1399   int i;
1400
1401   /* It is a fatal error for either of these to be NULL. */
1402   assert (progname && kpse->program_name);
1403   /* Do nothing if the name is unchanged. */
1404   if (STREQ(kpse->program_name, progname))
1405     return;
1406
1407   free (kpse->program_name);
1408   kpse->program_name = xstrdup (progname);
1409   kpathsea_xputenv(kpse, "progname", kpse->program_name);
1410
1411   /* Clear paths -- do we want the db path to be cleared? */
1412   for (i = 0; i != kpse_last_format; ++i) {
1413     /* Do not erase the cnf of db paths.  This means that the filename
1414        database is not rebuilt, nor are different configuration files
1415        searched.  The alternative is to tolerate a memory leak of up
1416        to 100k if this function is called. */
1417     if (i == kpse_cnf_format || i == kpse_db_format)
1418       continue;
1419     /* Wipe the path (it is tested) and the cnf_path because their
1420        values may differ with the new program name.  */
1421     if (kpse->format_info[i].path != NULL) {
1422       free (kpse->format_info[i].path);
1423       kpse->format_info[i].path = NULL;
1424     }
1425     /* We cannot free the cnf_path: it points into the cnf hash, which
1426        means all hell will break loose if we did. */
1427     if (kpse->format_info[i].cnf_path != NULL) {
1428       kpse->format_info[i].cnf_path = NULL;
1429     }
1430     /* We do not wipe the override_path at this point, though arguably
1431        we should provide new values.  It is not likely to matter for
1432        the programs that call this function. */
1433   }
1434 }
1435
1436 #if defined (KPSE_COMPAT_API)
1437 void
1438 kpse_reset_program_name (const_string progname)
1439 {
1440   kpathsea_reset_program_name (kpse_def, progname);
1441 }
1442 #endif