2
* File name.c - map full Unix file names to unique 8.3 names that
3
* would be valid on DOS.
6
Written by Eric Youngdale (1993).
8
Copyright 1993 Yggdrasil Computing, Incorporated
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)
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.
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. */
29
extern int allow_leading_dots;
32
* Function: iso9660_file_length
34
* Purpose: Map file name to 8.3 format, return length
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.
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.
45
int FDECL3(iso9660_file_length,
47
struct directory_entry *, sresult,
51
int chars_after_dot = 0;
52
int chars_before_dot = 0;
53
int current_length = 0;
64
result = sresult->isorec.name;
67
* For the '.' entry, generate the correct record, and return
70
if(strcmp(name,".") == 0)
80
* For the '..' entry, generate the correct record, and return
83
if(strcmp(name,"..") == 0)
94
* Now scan the directory one character at a time, and figure out
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.
104
last_dot = strrchr (pnt,'.');
105
if( (last_dot != NULL)
106
&& ( (last_dot[1] == '~')
107
|| (last_dot[1] == '\0')) )
111
last_dot = strrchr (pnt,'.');
118
if( strcmp(pnt,".DIR;1") == 0 )
125
* This character indicates a Unix style of backup file
126
* generated by some editors. Lower the priority of
137
* This character indicates a Unix style of backup file
138
* generated by some editors. Lower the priority of
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]
161
if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9'))
170
* If we have a name with multiple '.' characters, we ignore everything
171
* after we have gotten the extension.
180
* Spin past any iso9660 version number we might have.
184
if(*pnt >= '0' && *pnt <= '9')
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
200
if(full_iso9660_filenames)
202
/* Here we allow a more relaxed syntax. */
212
if(current_length < 30)
220
*result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt);
227
* Dos style filenames. We really restrict the
230
/* It would be nice to have .tar.gz transform to .tgz,
231
* .ps.gz to .psz, ...
235
if (!chars_before_dot && !allow_leading_dots)
237
/* DOS can't read files with dot first */
241
*result++ = '_'; /* Substitute underscore */
244
else if( pnt != last_dot )
247
* If this isn't the dot that we use for the extension,
248
* then change the character into a '_' instead.
250
if(chars_before_dot < 8)
274
if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot)
275
|| (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) )
282
if( !isascii (*pnt) )
288
*result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt;
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.
303
case '%': /* not legal DOS filename */
305
case ';': /* already handled */
306
case '.': /* already handled */
307
case ',': /* already handled */
310
/* V1 only separators */
319
/* Hmm - what to do here? Skip?
320
* Win95 looks like it substitutes '_'
324
} /* switch (*pnt) */
326
} /* if (chars_{after,before}_dot) ... */
327
} /* else *pnt == '.' */
328
} /* else DOS file names */
334
* OK, that wraps up the scan of the name. Now tidy up a few other
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'.
348
while (*pnt && *pnt != '~')
356
while(*pnt && *pnt != '~')
358
prio1 = 10*prio1 + *pnt - '0';
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
371
if (!seen_dot && !omit_period)
373
if (result) *result++ = '.';
376
if(!omit_version_number && !seen_semic)
391
sresult->priority = priority;
393
return (chars_before_dot + chars_after_dot + seen_dot + extra);