| 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 | } |