|
|
1.1 root 1: /*
2: ** DosFCheck - check file names for DOS consistency
3: **
4: ** Distribute freely, it only encourages DOS compatibility!
5: ** - DJ Delorie
6: */
7:
8: #include <stdio.h>
9: #ifdef __MSDOS__
10: #include <alloc.h>
11: #endif
12: #include <ctype.h>
13: #include <string.h>
14:
15: typedef struct ENT
16: {
17: struct ENT *next;
18: char *dos_name;
19: char *full_name;
20: char *path;
21: int tagged;
22: } ENT;
23:
24: ENT *eroot = 0;
25:
26: int first_inv = 1;
27: int first_msg = 1;
28:
29: /****************************************************************\
30: * Utility routines *
31: \****************************************************************/
32:
33: void
34: invalid_msg ()
35: {
36: if (first_inv)
37: {
38: if (first_msg)
39: first_msg = 0;
40: else
41: putchar ('\n');
42: printf ("The following files are not valid DOS file names:\n");
43: first_inv = 0;
44: }
45: }
46:
47: ENT *
48: alloc_ent ()
49: {
50: ENT *rv = (ENT *)malloc (sizeof (ENT));
51: if (rv == 0)
52: {
53: fprintf (stderr, "Unable to allocate memory for an ENT\n");
54: exit (1);
55: }
56: memset (rv, 0, sizeof (ENT));
57: return rv;
58: }
59:
60: void
61: fill_ent (ENT *ent, char *path)
62: {
63: char *first = path;
64: char *null = path+strlen (path);
65: char *last_slash = strrchr (path, '/');
66: char *cp, *dp;
67: int dots_seen, chars_seen;
68:
69: if (last_slash+1 == null)
70: {
71: * --null = '\0';
72: last_slash = strrchr (path, '/');
73: }
74:
75: if (!last_slash)
76: {
77: last_slash = first-1;
78: }
79:
80: if (null-last_slash < 13)
81: ent->dos_name = (char *)malloc (null-last_slash);
82: else
83: ent->dos_name = (char *)malloc (13);
84: ent->full_name = (char *)malloc (null-last_slash);
85: ent->path = (char *)malloc (last_slash-first+1);
86:
87: strcpy (ent->full_name, last_slash+1);
88: if (last_slash > first)
89: strncpy (ent->path, first, last_slash-first);
90: else
91: *ent->path = '\0';
92: ent->path[last_slash-first] = '\0';
93:
94: cp = last_slash+1;
95: dp = ent->dos_name;
96: dots_seen = 0;
97: chars_seen = 0;
98: while (1)
99: {
100: if (! *cp)
101: break;
102: switch (*cp)
103: {
104: case '.':
105: if (dots_seen == 1)
106: {
107: invalid_msg ();
108: printf ("%s - too many dots\n", path);
109: *dp = '\0';
110: break;
111: }
112: *dp++ = '.';
113: chars_seen = 0;
114: dots_seen++;
115: break;
116: case '"':
117: case '*':
118: case '+':
119: case ',':
120: case ';':
121: case '<':
122: case '=':
123: case '>':
124: case '?':
125: case '[':
126: case '\\':
127: case ']':
128: case '|':
129: invalid_msg ();
130: printf ("%s - invalid character `%c'\n", path, *cp);
131: *dp++ = '?';
132: chars_seen++;
133: break;
134: default:
135: if (dots_seen)
136: {
137: if (chars_seen >= 3)
138: break;
139: }
140: else
141: if (chars_seen >= 8)
142: break;
143: if ((*cp <= ' ') || (*cp >= 0x7f))
144: {
145: invalid_msg ();
146: printf ("%s - invalid character `%c'\n", path, *cp);
147: *dp++ = '?';
148: chars_seen++;
149: break;
150: }
151: if (islower (*cp))
152: *dp++ = toupper (*cp);
153: else
154: *dp++ = *cp;
155: chars_seen++;
156: break;
157: }
158: cp++;
159: }
160: *dp++ = '\0';
161: }
162:
163: int
164: compare_ent_dosname (ENT **e1, ENT **e2)
165: {
166: int r = strcmp ((*e1)->dos_name, (*e2)->dos_name);
167: if (r == 0)
168: r = strcmp ((*e1)->path, (*e2)->path);
169: if (r == 0)
170: r = strcmp ((*e1)->full_name, (*e2)->full_name);
171: return r;
172: }
173:
174: int
175: compare_ent_fullname (ENT **e1, ENT **e2)
176: {
177: int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14);
178: if (r == 0)
179: r = strcmp ((*e1)->path, (*e2)->path);
180: if (r == 0)
181: r = strcmp ((*e1)->full_name, (*e2)->full_name);
182: return r;
183: }
184:
185: char *
186: mpath (ENT *ent)
187: {
188: static char buf[500];
189: if (ent->path)
190: sprintf (buf, "%s/%s", ent->path, ent->full_name);
191: else
192: return ent->full_name;
193: return buf;
194: }
195:
196: /****************************************************************\
197: * List handling routines *
198: \****************************************************************/
199:
200: void
201: add_ent (ENT *ent)
202: {
203: ent->next = eroot;
204: eroot = ent;
205: }
206:
207: void
208: handle_input (char *line)
209: {
210: ENT *ent = alloc_ent ();
211: fill_ent (ent, line);
212: add_ent (ent);
213: }
214:
215: void
216: display_problems ()
217: {
218: ENT **elist, *ent;
219: int ecount, i, first, first_err;
220:
221: for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++);
222: elist = (ENT **)malloc (sizeof (ENT *) * ecount);
223: for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++)
224: elist[ecount] = ent;
225:
226: qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
227:
228: first = 1;
229: first_err = 1;
230: for (i=0; i<ecount-1; i++)
231: {
232: if ((strcmp (elist[i]->dos_name, elist[i+1]->dos_name) == 0) &&
233: (strcmp (elist[i]->path, elist[i+1]->path) == 0))
234: {
235: if (first_err)
236: {
237: if (first_msg)
238: first_msg = 0;
239: else
240: putchar ('\n');
241: printf ("The following resolve to the same DOS file names:\n");
242: first_err = 0;
243: }
244: if (first)
245: {
246: printf ("%14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
247: first = 0;
248: }
249: printf ("\t\t %s\n", mpath (elist[i+1]));
250: }
251: else
252: first = 1;
253: }
254:
255: qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
256:
257: first = 1;
258: first_err = 1;
259: for (i=0; i<ecount-1; i++)
260: {
261: if ((strncmp (elist[i]->full_name, elist[i+1]->full_name, 14) == 0) &&
262: (strcmp (elist[i]->path, elist[i+1]->path) == 0))
263: {
264: if (first_err)
265: {
266: if (first_msg)
267: first_msg = 0;
268: else
269: putchar ('\n');
270: printf ("The following resolve to the same SysV file names:\n");
271: first_err = 0;
272: }
273: if (first)
274: {
275: printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
276: first = 0;
277: elist[i]->tagged = 1;
278: }
279: printf ("\t\t %s\n", mpath (elist[i+1]));
280: elist[i+1]->tagged = 1;
281: }
282: else
283: first = 1;
284: }
285:
286: first_err = 1;
287: for (i=0; i<ecount; i++)
288: {
289: if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
290: {
291: if (first_err)
292: {
293: if (first_msg)
294: first_msg = 0;
295: else
296: putchar ('\n');
297: printf ("The following file names are too long for SysV:\n");
298: first_err = 0;
299: }
300: printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
301: }
302: }
303: }
304:
305: /****************************************************************\
306: * Main entry point *
307: \****************************************************************/
308:
309: main (int argc, char **argv)
310: {
311: FILE *input = stdin;
312: if (argc > 1)
313: {
314: input = fopen (argv[1], "r");
315: if (!input)
316: {
317: perror (argv[1]);
318: exit (1);
319: }
320: }
321: while (1)
322: {
323: char line[500];
324: char *lp;
325: fgets (line, 500, input);
326: if (feof (input))
327: break;
328: lp = line+strlen (line);
329: while ((lp != line) && (*lp <= ' '))
330: lp--;
331: lp[1] = 0;
332: handle_input (line);
333: }
334: display_problems ();
335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.