File: | src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/name.c |
Warning: | line 391, column 21 Access to field 'priority' results in a dereference of a null pointer (loaded from variable 'sresult') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * File name.c - map full Unix file names to unique 8.3 names that | |||
3 | * would be valid on DOS. | |||
4 | * | |||
5 | ||||
6 | Written by Eric Youngdale (1993). | |||
7 | ||||
8 | Copyright 1993 Yggdrasil Computing, Incorporated | |||
9 | ||||
10 | This program is free software; you can redistribute it and/or modify | |||
11 | it under the terms of the GNU General Public License as published by | |||
12 | the Free Software Foundation; either version 2, or (at your option) | |||
13 | any later version. | |||
14 | ||||
15 | This program is distributed in the hope that it will be useful, | |||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
18 | GNU General Public License for more details. | |||
19 | ||||
20 | You should have received a copy of the GNU General Public License | |||
21 | along with this program; if not, write to the Free Software | |||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
23 | ||||
24 | #include "config.h" | |||
25 | #include "mkisofs.h" | |||
26 | ||||
27 | #include <ctype.h> | |||
28 | ||||
29 | extern int allow_leading_dots; | |||
30 | ||||
31 | /* | |||
32 | * Function: iso9660_file_length | |||
33 | * | |||
34 | * Purpose: Map file name to 8.3 format, return length | |||
35 | * of result. | |||
36 | * | |||
37 | * Arguments: name file name we need to map. | |||
38 | * sresult directory entry structure to contain mapped name. | |||
39 | * dirflag flag indicating whether this is a directory or not. | |||
40 | * | |||
41 | * Notes: This procedure probably needs to be rationalized somehow. | |||
42 | * New options to affect the behavior of this function | |||
43 | * would also be nice to have. | |||
44 | */ | |||
45 | int FDECL3(iso9660_file_length,iso9660_file_length(const char* name, struct directory_entry * sresult, int dirflag) | |||
46 | const char*, name,iso9660_file_length(const char* name, struct directory_entry * sresult, int dirflag) | |||
47 | struct directory_entry *, sresult,iso9660_file_length(const char* name, struct directory_entry * sresult, int dirflag) | |||
48 | int, dirflag)iso9660_file_length(const char* name, struct directory_entry * sresult, int dirflag) | |||
49 | { | |||
50 | char * c; | |||
51 | int chars_after_dot = 0; | |||
52 | int chars_before_dot = 0; | |||
53 | int current_length = 0; | |||
54 | int extra = 0; | |||
55 | int ignore = 0; | |||
56 | char * last_dot; | |||
57 | const char * pnt; | |||
58 | int priority = 32767; | |||
59 | char * result; | |||
60 | int seen_dot = 0; | |||
61 | int seen_semic = 0; | |||
62 | int tildes = 0; | |||
63 | ||||
64 | result = sresult->isorec.name; | |||
65 | ||||
66 | /* | |||
67 | * For the '.' entry, generate the correct record, and return | |||
68 | * 1 for the length. | |||
69 | */ | |||
70 | if(strcmp(name,".") == 0) | |||
| ||||
71 | { | |||
72 | if(result) | |||
73 | { | |||
74 | *result = 0; | |||
75 | } | |||
76 | return 1; | |||
77 | } | |||
78 | ||||
79 | /* | |||
80 | * For the '..' entry, generate the correct record, and return | |||
81 | * 1 for the length. | |||
82 | */ | |||
83 | if(strcmp(name,"..") == 0) | |||
84 | { | |||
85 | if(result) | |||
86 | { | |||
87 | *result++ = 1; | |||
88 | *result++ = 0; | |||
89 | } | |||
90 | return 1; | |||
91 | } | |||
92 | ||||
93 | /* | |||
94 | * Now scan the directory one character at a time, and figure out | |||
95 | * what to do. | |||
96 | */ | |||
97 | pnt = name; | |||
98 | ||||
99 | /* | |||
100 | * Find the '.' that we intend to use for the extension. Usually this | |||
101 | * is the last dot, but if we have . followed by nothing or a ~, we | |||
102 | * would consider this to be unsatisfactory, and we keep searching. | |||
103 | */ | |||
104 | last_dot = strrchr (pnt,'.'); | |||
105 | if( (last_dot != NULL((void *)0)) | |||
106 | && ( (last_dot[1] == '~') | |||
107 | || (last_dot[1] == '\0')) ) | |||
108 | { | |||
109 | c = last_dot; | |||
110 | *c = '\0'; | |||
111 | last_dot = strrchr (pnt,'.'); | |||
112 | *c = '.'; | |||
113 | } | |||
114 | ||||
115 | while(*pnt) | |||
116 | { | |||
117 | #ifdef VMS | |||
118 | if( strcmp(pnt,".DIR;1") == 0 ) | |||
119 | { | |||
120 | break; | |||
121 | } | |||
122 | #endif | |||
123 | ||||
124 | /* | |||
125 | * This character indicates a Unix style of backup file | |||
126 | * generated by some editors. Lower the priority of | |||
127 | * the file. | |||
128 | */ | |||
129 | if(*pnt == '#') | |||
130 | { | |||
131 | priority = 1; | |||
132 | pnt++; | |||
133 | continue; | |||
134 | } | |||
135 | ||||
136 | /* | |||
137 | * This character indicates a Unix style of backup file | |||
138 | * generated by some editors. Lower the priority of | |||
139 | * the file. | |||
140 | */ | |||
141 | if(*pnt == '~') | |||
142 | { | |||
143 | priority = 1; | |||
144 | tildes++; | |||
145 | pnt++; | |||
146 | continue; | |||
147 | } | |||
148 | ||||
149 | /* | |||
150 | * This might come up if we had some joker already try and put | |||
151 | * iso9660 version numbers into the file names. This would be | |||
152 | * a silly thing to do on a Unix box, but we check for it | |||
153 | * anyways. If we see this, then we don't have to add our | |||
154 | * own version number at the end. | |||
155 | * UNLESS the ';' is part of the filename and no version | |||
156 | * number is following. [VK] | |||
157 | */ | |||
158 | if(*pnt == ';') | |||
159 | { | |||
160 | /* [VK] */ | |||
161 | if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9')) | |||
162 | { | |||
163 | pnt++; | |||
164 | ignore++; | |||
165 | continue; | |||
166 | } | |||
167 | } | |||
168 | ||||
169 | /* | |||
170 | * If we have a name with multiple '.' characters, we ignore everything | |||
171 | * after we have gotten the extension. | |||
172 | */ | |||
173 | if(ignore) | |||
174 | { | |||
175 | pnt++; | |||
176 | continue; | |||
177 | } | |||
178 | ||||
179 | /* | |||
180 | * Spin past any iso9660 version number we might have. | |||
181 | */ | |||
182 | if(seen_semic) | |||
183 | { | |||
184 | if(*pnt >= '0' && *pnt <= '9') | |||
185 | { | |||
186 | *result++ = *pnt; | |||
187 | } | |||
188 | extra++; | |||
189 | pnt++; | |||
190 | continue; | |||
191 | } | |||
192 | ||||
193 | /* | |||
194 | * If we have full names, the names we generate will not | |||
195 | * work on a DOS machine, since they are not guaranteed | |||
196 | * to be 8.3. Nonetheless, in many cases this is a useful | |||
197 | * option. We still only allow one '.' character in the | |||
198 | * name, however. | |||
199 | */ | |||
200 | if(full_iso9660_filenames) | |||
201 | { | |||
202 | /* Here we allow a more relaxed syntax. */ | |||
203 | if(*pnt == '.') | |||
204 | { | |||
205 | if (seen_dot) | |||
206 | { | |||
207 | ignore++; | |||
208 | continue; | |||
209 | } | |||
210 | seen_dot++; | |||
211 | } | |||
212 | if(current_length < 30) | |||
213 | { | |||
214 | if(!isascii((unsigned char)*pnt)) | |||
215 | { | |||
216 | *result++ = '_'; | |||
217 | } | |||
218 | else | |||
219 | { | |||
220 | *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt); | |||
221 | } | |||
222 | } | |||
223 | } | |||
224 | else | |||
225 | { | |||
226 | /* | |||
227 | * Dos style filenames. We really restrict the | |||
228 | * names here. | |||
229 | */ | |||
230 | /* It would be nice to have .tar.gz transform to .tgz, | |||
231 | * .ps.gz to .psz, ... | |||
232 | */ | |||
233 | if(*pnt == '.') | |||
234 | { | |||
235 | if (!chars_before_dot && !allow_leading_dots) | |||
236 | { | |||
237 | /* DOS can't read files with dot first */ | |||
238 | chars_before_dot++; | |||
239 | if (result) | |||
240 | { | |||
241 | *result++ = '_'; /* Substitute underscore */ | |||
242 | } | |||
243 | } | |||
244 | else if( pnt != last_dot ) | |||
245 | { | |||
246 | /* | |||
247 | * If this isn't the dot that we use for the extension, | |||
248 | * then change the character into a '_' instead. | |||
249 | */ | |||
250 | if(chars_before_dot < 8) | |||
251 | { | |||
252 | chars_before_dot++; | |||
253 | if(result) | |||
254 | { | |||
255 | *result++ = '_'; | |||
256 | } | |||
257 | } | |||
258 | } | |||
259 | else | |||
260 | { | |||
261 | if (seen_dot) | |||
262 | { | |||
263 | ignore++; continue; | |||
264 | } | |||
265 | if(result) | |||
266 | { | |||
267 | *result++ = '.'; | |||
268 | } | |||
269 | seen_dot++; | |||
270 | } | |||
271 | } | |||
272 | else | |||
273 | { | |||
274 | if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot) | |||
275 | || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) ) | |||
276 | { | |||
277 | if(result) | |||
278 | { | |||
279 | switch (*pnt) | |||
280 | { | |||
281 | default: | |||
282 | if(!isascii((unsigned char)*pnt)) | |||
283 | { | |||
284 | *result++ = '_'; | |||
285 | } | |||
286 | else | |||
287 | { | |||
288 | *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt; | |||
289 | } | |||
290 | break; | |||
291 | ||||
292 | /* | |||
293 | * Descriptions of DOS's 'Parse Filename' | |||
294 | * (function 29H) describes V1 and V2.0+ | |||
295 | * separator and terminator characters. | |||
296 | * These characters in a DOS name make | |||
297 | * the file visible but un-manipulable | |||
298 | * (all useful operations error off. | |||
299 | */ | |||
300 | /* separators */ | |||
301 | case '+': | |||
302 | case '=': | |||
303 | case '%': /* not legal DOS filename */ | |||
304 | case ':': | |||
305 | case ';': /* already handled */ | |||
306 | case '.': /* already handled */ | |||
307 | case ',': /* already handled */ | |||
308 | case '\t': | |||
309 | case ' ': | |||
310 | /* V1 only separators */ | |||
311 | case '/': | |||
312 | case '"': | |||
313 | case '[': | |||
314 | case ']': | |||
315 | /* terminators */ | |||
316 | case '>': | |||
317 | case '<': | |||
318 | case '|': | |||
319 | /* Hmm - what to do here? Skip? | |||
320 | * Win95 looks like it substitutes '_' | |||
321 | */ | |||
322 | *result++ = '_'; | |||
323 | break; | |||
324 | } /* switch (*pnt) */ | |||
325 | } /* if (result) */ | |||
326 | } /* if (chars_{after,before}_dot) ... */ | |||
327 | } /* else *pnt == '.' */ | |||
328 | } /* else DOS file names */ | |||
329 | current_length++; | |||
330 | pnt++; | |||
331 | } /* while (*pnt) */ | |||
332 | ||||
333 | /* | |||
334 | * OK, that wraps up the scan of the name. Now tidy up a few other | |||
335 | * things. | |||
336 | */ | |||
337 | ||||
338 | /* | |||
339 | * Look for emacs style of numbered backups, like foo.c.~3~. If | |||
340 | * we see this, convert the version number into the priority | |||
341 | * number. In case of name conflicts, this is what would end | |||
342 | * up being used as the 'extension'. | |||
343 | */ | |||
344 | if(tildes
| |||
345 | { | |||
346 | int prio1 = 0; | |||
347 | pnt = name; | |||
348 | while (*pnt && *pnt != '~') | |||
349 | { | |||
350 | pnt++; | |||
351 | } | |||
352 | if (*pnt) | |||
353 | { | |||
354 | pnt++; | |||
355 | } | |||
356 | while(*pnt && *pnt != '~') | |||
357 | { | |||
358 | prio1 = 10*prio1 + *pnt - '0'; | |||
359 | pnt++; | |||
360 | } | |||
361 | priority = prio1; | |||
362 | } | |||
363 | ||||
364 | /* | |||
365 | * If this is not a directory, force a '.' in case we haven't | |||
366 | * seen one, and add a version number if we haven't seen one | |||
367 | * of those either. | |||
368 | */ | |||
369 | if (!dirflag) | |||
370 | { | |||
371 | if (!seen_dot && !omit_period) | |||
372 | { | |||
373 | if (result) *result++ = '.'; | |||
374 | extra++; | |||
375 | } | |||
376 | if(!omit_version_number && !seen_semic) | |||
377 | { | |||
378 | if(result) | |||
379 | { | |||
380 | *result++ = ';'; | |||
381 | *result++ = '1'; | |||
382 | }; | |||
383 | extra += 2; | |||
384 | } | |||
385 | } | |||
386 | ||||
387 | if(result) | |||
388 | { | |||
389 | *result++ = 0; | |||
390 | } | |||
391 | sresult->priority = priority; | |||
| ||||
392 | ||||
393 | return (chars_before_dot + chars_after_dot + seen_dot + extra); | |||
394 | } |