1 /* emtexdir.c -- written by Eberhard Mattes, donated to the public domain */
4 #include <emx/syscalls.h>
8 #if defined(DJGPP) || defined(GO32)
20 void (*emtex_dir_find_callback
)(const char *name
, int ok
) = NULL
;
22 static int setup_add (struct emtex_dir
*dst
, const char *path
)
26 if (dst
->used
>= dst
->alloc
)
29 dst
->list
= realloc (dst
->list
, dst
->alloc
* sizeof (*dst
->list
));
30 if (dst
->list
== NULL
)
36 dst
->list
[dst
->used
++] = p
;
41 static int setup_subdir (struct emtex_dir
*dst
, char *path
, size_t add
,
42 unsigned flags
, int recurse
)
48 struct ll_findbuffer find
;
52 strcpy (path
+ add
, "*.*");
54 ok
= __findfirst (path
, 0x10, &find
) == 0;
56 ok
= ll_findfirst (path
, 0x10, &find
);
60 if ((find
.attr
& 0x10)
61 && !(strcmp (find
.name
, ".") == 0 || strcmp (find
.name
, "..") == 0))
63 len
= strlen (find
.name
);
64 memcpy (path
+ add
, find
.name
, len
);
67 if (!setup_add (dst
, path
))
71 ok
= __findnext (&find
) == 0;
73 ok
= ll_findnext (&find
);
81 strcpy (path
, dst
->list
[i
]);
82 if (!setup_subdir (dst
, path
, strlen (path
), flags
, TRUE
))
91 static int setup_dir (struct emtex_dir
*dst
, char *path
,
92 const char *base_dir
, size_t base_dir_len
,
98 memcpy (path
, base_dir
, base_dir_len
);
100 if ((flags
& EDS_BANG
) && sub_dir
== NULL
)
102 flags
&= ~(EDS_ONESUBDIR
|EDS_ALLSUBDIR
);
103 if (i
>= 2 && path
[i
-1] == '!' && path
[i
-2] == '!')
105 flags
|= EDS_ALLSUBDIR
;
108 else if (i
>= 1 && path
[i
-1] == '!')
110 flags
|= EDS_ONESUBDIR
;
114 if (sub_dir
!= NULL
&& *sub_dir
!= 0)
116 if (i
!= 0 && path
[i
-1] != ':' && path
[i
-1] != '/' && path
[i
-1] != '\\')
118 len
= strlen (sub_dir
);
119 memcpy (path
+i
, sub_dir
, len
);
122 if (path
[i
-1] != ':' && path
[i
-1] != '/' && path
[i
-1] != '\\')
125 if (!setup_add (dst
, path
))
127 if (flags
& EDS_ALLSUBDIR
)
128 return (setup_subdir (dst
, path
, i
, flags
, TRUE
));
129 else if (flags
& EDS_ONESUBDIR
)
130 return (setup_subdir (dst
, path
, i
, flags
, FALSE
));
136 /*static */int setup_list (struct emtex_dir
*dst
, char *path
,
137 const char *list
, unsigned flags
)
144 while (*list
== ' ' || *list
== '\t')
149 while (*end
!= 0 && *end
!= ';')
152 while (i
> 0 && (list
[i
-1] == ' ' || list
[i
-1] == '\t'))
154 if (i
!= 0 && !setup_dir (dst
, path
, list
, i
, NULL
, flags
))
163 int emtex_dir_setup (struct emtex_dir
*ed
, const char *env
, const char *dir
,
172 if (env
!= NULL
&& (val
= getenv (env
)) != NULL
)
173 return (setup_list (ed
, path
, val
, flags
));
174 else if ((val
= getenv ("EMTEXDIR")) != NULL
)
175 return (setup_dir (ed
, path
, val
, strlen (val
), dir
, flags
));
177 return (setup_dir (ed
, path
, "\\emtex", 6, dir
, flags
));
181 static void pretty (char *path
, unsigned flags
)
185 if (flags
& EDF_FSLASH
)
186 for (p
= path
; *p
!= 0; ++p
)
193 if (dst_size < 1) return (EDT_TOOLONG); \
194 *dst++ = (C); --dst_size
196 int emtex_dir_trunc (char *dst
, size_t dst_size
, const char *src
,
197 unsigned flags
, int method
)
199 int len
, truncated
, dot
;
201 if (src
[0] != 0 && src
[1] == ':')
208 truncated
= FALSE
; dot
= FALSE
; len
= 0;
215 return (truncated
? EDT_CHANGED
: EDT_UNCHANGED
);
218 return (EDT_INVALID
);
223 len
= 0; dot
= FALSE
;
228 return (EDT_INVALID
);
231 /* ".." is allowed -- don't return EDT_INVALID for the next
234 if (!(len
== 0 && src
[1] == '.'
235 && (src
[2] == 0 || src
[2] == '/' || src
[2] == '\\')))
244 else if (!dot
&& len
== 8)
266 static int find2 (const char *name
, unsigned flags
)
270 ok
= (access (name
, 4) == 0);
271 if (flags
& EDF_TRACE
)
272 emtex_dir_find_callback (name
, ok
);
277 static int find1 (char *path
, size_t path_size
, const char *dir
,
278 const char *fname
, unsigned flags
)
288 if (tmp
>= sizeof (buf
))
290 memcpy (buf
, dir
, tmp
);
293 tmp
= strlen (fname
);
294 if (len
+ tmp
>= sizeof (buf
))
296 memcpy (buf
+ len
, fname
, tmp
+ 1);
299 /* disabled for Win95's long file name support */
300 /* -- Wonkoo Kim (wkim+@pitt.edu), May 18, 1997 */
301 if (_osmode
== DOS_MODE
)
303 rc
= emtex_dir_trunc (path
, path_size
, buf
, flags
, EDT_5_PLUS_3
);
304 if ((rc
== EDT_UNCHANGED
|| rc
== EDT_CHANGED
) && find2 (path
, flags
))
306 pretty (path
, flags
);
309 rc
= emtex_dir_trunc (path
, path_size
, buf
, flags
, EDT_8
);
310 if (rc
== EDT_CHANGED
&& find2 (path
, flags
))
312 pretty (path
, flags
);
320 if (len
< path_size
&& find2 (buf
, flags
))
322 memcpy (path
, buf
, len
+ 1);
323 pretty (path
, flags
);
326 for (method
= 0; method
< 2; ++method
)
328 rc
= emtex_dir_trunc (path
, path_size
, buf
, flags
, method
);
329 if (rc
== EDT_CHANGED
&& find2 (path
, flags
))
331 pretty (path
, flags
);
340 int emtex_dir_find (char *path
, size_t path_size
,
341 const struct emtex_dir
*ed
,
342 const char *fname
, unsigned flags
)
348 for (p
= fname
; *p
!= 0; ++p
)
349 if (*p
== ':' || *p
== '/' || *p
== '\\')
356 return (find1 (path
, path_size
, NULL
, fname
, flags
));
358 if ((flags
& EDF_CWD
) && find1 (path
, path_size
, NULL
, fname
, flags
))
361 for (i
= 0; i
< ed
->used
; ++i
)
362 if (find1 (path
, path_size
, ed
->list
[i
], fname
, flags
))
372 int main (int argc
, char *argv
[])
376 unsigned flags1
, flags2
;
381 puts ("Usage: emtexdir <flags> <flags> <env> <dir> <fname>");
385 flags1
= (unsigned)strtol (argv
[1], NULL
, 0);
386 flags2
= (unsigned)strtol (argv
[2], NULL
, 0);
388 if (!emtex_dir_setup (&ed
, argv
[3], argv
[4], flags1
))
390 fputs ("emtex_dir_setup failed\n", stderr
);
394 printf ("Directories:\n");
395 for (i
= 0; i
< ed
.used
; ++i
)
396 printf (" %s\n", ed
.list
[i
]);
398 if (!emtex_dir_find (path
, sizeof (path
), &ed
, argv
[5], flags2
))
399 puts ("File not found");
401 printf ("Path: %s\n", path
);