|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - file.c
1.1 root 3:
1.1.1.5 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
1.1.1.6 root 7: Common file access functions.
1.1 root 8: */
1.1.1.9 ! root 9: char File_rcsid[] = "Hatari $Id: file.c,v 1.24 2005/09/13 01:10:09 thothy Exp $";
1.1 root 10:
11: #include <sys/types.h>
12: #include <sys/stat.h>
13: #include <fcntl.h>
1.1.1.6 root 14: #include <unistd.h>
15:
16: #include <zlib.h>
1.1 root 17:
18: #include "main.h"
1.1.1.7 root 19: #include "dialog.h"
1.1 root 20: #include "file.h"
21: #include "createBlankImage.h"
22:
1.1.1.3 root 23:
1.1.1.6 root 24: #if defined(__BEOS__) || (defined(__sun) && defined(__SVR4))
25: /* The scandir() and alphasort() functions aren't available on
26: * BeOS and Solaris, so let's declare them here... */
1.1.1.3 root 27: #include <dirent.h>
28:
29: #undef DIRSIZ
30:
31: #define DIRSIZ(dp) \
32: ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
33: (((dp)->d_reclen + 1 + 3) &~ 3))
34:
1.1.1.6 root 35: #if defined(__sun) && defined(__SVR4)
1.1.1.7 root 36: # define dirfd(d) ((d)->dd_fd)
37: #elif defined(__BEOS__)
38: # define dirfd(d) ((d)->fd)
1.1.1.6 root 39: #endif
40:
1.1 root 41:
42: /*-----------------------------------------------------------------------*/
43: /*
1.1.1.3 root 44: Alphabetic order comparison routine for those who want it.
1.1 root 45: */
1.1.1.3 root 46: int alphasort(const void *d1, const void *d2)
1.1 root 47: {
1.1.1.8 root 48: return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
1.1.1.3 root 49: }
1.1 root 50:
51:
1.1.1.3 root 52: /*-----------------------------------------------------------------------*/
53: /*
54: Scan a directory for all its entries
55: */
1.1.1.8 root 56: int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
1.1.1.3 root 57: {
1.1.1.8 root 58: struct dirent *d, *p, **names;
1.1.1.3 root 59: struct stat stb;
1.1.1.8 root 60: size_t nitems;
61: size_t arraysz;
1.1.1.3 root 62: DIR *dirp;
1.1 root 63:
1.1.1.3 root 64: if ((dirp = opendir(dirname)) == NULL)
65: return(-1);
1.1 root 66:
1.1.1.7 root 67: if (fstat(dirfd(dirp), &stb) < 0)
1.1.1.3 root 68: return(-1);
1.1 root 69:
1.1.1.3 root 70: /*
71: * estimate the array size by taking the size of the directory file
72: * and dividing it by a multiple of the minimum size entry.
73: */
74: arraysz = (stb.st_size / 24);
1.1 root 75:
1.1.1.3 root 76: names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
77: if (names == NULL)
78: return(-1);
1.1 root 79:
1.1.1.3 root 80: nitems = 0;
1.1 root 81:
1.1.1.3 root 82: while ((d = readdir(dirp)) != NULL) {
1.1 root 83:
1.1.1.8 root 84: if (sdfilter != NULL && !(*sdfilter)(d))
1.1.1.3 root 85: continue; /* just selected names */
1.1 root 86:
1.1.1.3 root 87: /*
88: * Make a minimum size copy of the data
89: */
1.1 root 90:
1.1.1.3 root 91: p = (struct dirent *)malloc(DIRSIZ(d));
92: if (p == NULL)
93: return(-1);
1.1 root 94:
1.1.1.3 root 95: p->d_ino = d->d_ino;
96: p->d_reclen = d->d_reclen;
97: /*p->d_namlen = d->d_namlen;*/
1.1.1.7 root 98: memcpy(p->d_name, d->d_name, p->d_reclen + 1);
1.1 root 99:
1.1.1.3 root 100: /*
101: * Check to make sure the array has space left and
102: * realloc the maximum size.
103: */
1.1 root 104:
1.1.1.3 root 105: if (++nitems >= arraysz) {
1.1 root 106:
1.1.1.7 root 107: if (fstat(dirfd(dirp), &stb) < 0)
1.1.1.3 root 108: return(-1); /* just might have grown */
1.1 root 109:
1.1.1.3 root 110: arraysz = stb.st_size / 12;
1.1 root 111:
1.1.1.3 root 112: names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
113: if (names == NULL)
114: return(-1);
115: }
1.1 root 116:
1.1.1.3 root 117: names[nitems-1] = p;
118: }
1.1 root 119:
1.1.1.3 root 120: closedir(dirp);
1.1 root 121:
1.1.1.3 root 122: if (nitems && dcomp != NULL)
123: qsort(names, nitems, sizeof(struct dirent *), dcomp);
1.1 root 124:
1.1.1.3 root 125: *namelist = names;
126:
1.1.1.8 root 127: return nitems;
1.1 root 128: }
129:
130:
1.1.1.3 root 131: #endif /* __BEOS__ */
132:
1.1 root 133:
1.1.1.2 root 134:
135: /*-----------------------------------------------------------------------*/
1.1 root 136: /*
137: Remove any '/'s from end of filenames, but keeps / intact
138: */
139: void File_CleanFileName(char *pszFileName)
140: {
1.1.1.3 root 141: int len;
142:
143: len = strlen(pszFileName);
144:
145: /* Security length check: */
1.1.1.6 root 146: if (len > FILENAME_MAX)
1.1.1.3 root 147: {
1.1.1.6 root 148: pszFileName[FILENAME_MAX-1] = 0;
149: len = FILENAME_MAX;
1.1.1.3 root 150: }
1.1 root 151:
1.1.1.2 root 152: /* Remove end slash from filename! But / remains! Doh! */
1.1.1.3 root 153: if( len>2 && pszFileName[len-1]=='/' )
154: pszFileName[len-1] = 0;
1.1 root 155: }
156:
1.1.1.2 root 157:
158: /*-----------------------------------------------------------------------*/
1.1 root 159: /*
160: Add '/' to end of filename
161: */
162: void File_AddSlashToEndFileName(char *pszFileName)
163: {
1.1.1.2 root 164: /* Check dir/filenames */
1.1.1.8 root 165: if (strlen(pszFileName)!=0)
166: {
1.1 root 167: if (pszFileName[strlen(pszFileName)-1]!='/')
1.1.1.2 root 168: strcat(pszFileName,"/"); /* Must use end slash */
1.1 root 169: }
170: }
171:
1.1.1.3 root 172:
1.1 root 173: /*-----------------------------------------------------------------------*/
174: /*
175: Does filename extension match? If so, return TRUE
176: */
1.1.1.8 root 177: BOOL File_DoesFileExtensionMatch(const char *pszFileName, const char *pszExtension)
1.1 root 178: {
179: if ( strlen(pszFileName) < strlen(pszExtension) )
180: return(FALSE);
181: /* Is matching extension? */
182: if ( !strcasecmp(&pszFileName[strlen(pszFileName)-strlen(pszExtension)], pszExtension) )
183: return(TRUE);
184:
185: /* No */
186: return(FALSE);
187: }
188:
1.1.1.2 root 189:
190: /*-----------------------------------------------------------------------*/
1.1 root 191: /*
192: Check if filename is from root
193:
194: Return TRUE if filename is '/', else give FALSE
195: */
196: BOOL File_IsRootFileName(char *pszFileName)
197: {
198: if (pszFileName[0]=='\0') /* If NULL string return! */
199: return(FALSE);
200:
201: if (pszFileName[0]=='/')
202: return(TRUE);
203:
204: return(FALSE);
205: }
206:
1.1.1.2 root 207:
208: /*-----------------------------------------------------------------------*/
1.1 root 209: /*
210: Return string, to remove 'C:' part of filename
211: */
1.1.1.8 root 212: const char *File_RemoveFileNameDrive(const char *pszFileName)
1.1 root 213: {
214: if ( (pszFileName[0]!='\0') && (pszFileName[1]==':') )
215: return(&pszFileName[2]);
216: else
217: return(pszFileName);
218: }
219:
220:
1.1.1.2 root 221: /*-----------------------------------------------------------------------*/
1.1 root 222: /*
223: Check if filename end with a '/'
224:
225: Return TRUE if filename ends with '/'
226: */
227: BOOL File_DoesFileNameEndWithSlash(char *pszFileName)
228: {
229: if (pszFileName[0]=='\0') /* If NULL string return! */
230: return(FALSE);
231:
1.1.1.3 root 232: /* Does string end in a '/'? */
1.1 root 233: if (pszFileName[strlen(pszFileName)-1]=='/')
234: return(TRUE);
235:
236: return(FALSE);
237: }
238:
1.1.1.2 root 239:
240: /*-----------------------------------------------------------------------*/
1.1 root 241: /*
242: Remove any double '/'s from end of filenames. So just the one
243: */
244: void File_RemoveFileNameTrailingSlashes(char *pszFileName)
245: {
246: int Length;
247:
248: /* Do have slash at end of filename? */
249: Length = strlen(pszFileName);
1.1.1.8 root 250: if (Length>=3)
251: {
252: if (pszFileName[Length-1]=='/') /* Yes, have one previous? */
253: {
1.1 root 254: if (pszFileName[Length-2]=='/')
255: pszFileName[Length-1] = '\0'; /* then remove it! */
256: }
257: }
258: }
259:
260:
1.1.1.2 root 261: /*-----------------------------------------------------------------------*/
1.1 root 262: /*
1.1.1.9 ! root 263: Read file from disk into memory, allocate memory for it if need to (pass
1.1.1.6 root 264: Address as NULL).
1.1 root 265: */
1.1.1.8 root 266: void *File_Read(char *pszFileName, void *pAddress, long *pFileSize, const char *ppszExts[])
1.1 root 267: {
1.1.1.6 root 268: void *pFile = NULL;
269: long FileSize = 0;
1.1 root 270:
271: /* Does the file exist? If not, see if can scan for other extensions and try these */
1.1.1.6 root 272: if (!File_Exists(pszFileName) && ppszExts)
273: {
1.1 root 274: /* Try other extensions, if suceeds correct filename is now in 'pszFileName' */
1.1.1.6 root 275: File_FindPossibleExtFileName(pszFileName, ppszExts);
1.1 root 276: }
277:
1.1.1.6 root 278: /* Normal file or gzipped file? */
279: if (File_DoesFileExtensionMatch(pszFileName, ".gz"))
280: {
281: gzFile hGzFile;
282: /* Open and read gzipped file */
283: hGzFile = gzopen(pszFileName, "rb");
284: if (hGzFile != NULL)
285: {
286: /* Find size of file: */
287: do
288: {
289: /* Seek through the file until we hit the end... */
290: gzseek(hGzFile, 1024, SEEK_CUR);
291: }
292: while (!gzeof(hGzFile));
293: FileSize = gztell(hGzFile);
294: gzrewind(hGzFile);
295: /* Find pointer to where to load, allocate memory if pass NULL */
296: if (pAddress)
297: pFile = pAddress;
298: else
299: pFile = malloc(FileSize);
300: /* Read in... */
301: if (pFile)
302: gzread(hGzFile, pFile, FileSize);
1.1 root 303:
1.1.1.6 root 304: gzclose(hGzFile);
305: }
306: }
307: else
308: {
1.1.1.9 ! root 309: FILE *hDiskFile;
1.1.1.6 root 310: /* Open and read normal file */
1.1.1.9 ! root 311: hDiskFile = fopen(pszFileName, "rb");
! 312: if (hDiskFile != NULL)
1.1.1.6 root 313: {
314: /* Find size of file: */
1.1.1.9 ! root 315: fseek(hDiskFile, 0, SEEK_END);
! 316: FileSize = ftell(hDiskFile);
! 317: fseek(hDiskFile, 0, SEEK_SET);
1.1.1.6 root 318: /* Find pointer to where to load, allocate memory if pass NULL */
319: if (pAddress)
320: pFile = pAddress;
321: else
322: pFile = malloc(FileSize);
323: /* Read in... */
324: if (pFile)
1.1.1.9 ! root 325: fread(pFile, 1, FileSize, hDiskFile);
1.1.1.6 root 326:
1.1.1.9 ! root 327: fclose(hDiskFile);
1.1.1.6 root 328: }
1.1 root 329: }
1.1.1.6 root 330:
1.1.1.2 root 331: /* Store size of file we read in (or 0 if failed) */
1.1 root 332: if (pFileSize)
333: *pFileSize = FileSize;
334:
335: return(pFile); /* Return to where read in/allocated */
336: }
337:
1.1.1.2 root 338:
339: /*-----------------------------------------------------------------------*/
1.1 root 340: /*
1.1.1.9 ! root 341: Save file to disk, return FALSE if errors
1.1 root 342: */
1.1.1.6 root 343: BOOL File_Save(char *pszFileName, void *pAddress, size_t Size, BOOL bQueryOverwrite)
1.1 root 344: {
1.1.1.6 root 345: BOOL bRet = FALSE;
1.1 root 346:
347: /* Check if need to ask user if to overwrite */
1.1.1.6 root 348: if (bQueryOverwrite)
349: {
1.1 root 350: /* If file exists, ask if OK to overwrite */
351: if (!File_QueryOverwrite(pszFileName))
352: return(FALSE);
353: }
354:
1.1.1.6 root 355: /* Normal file or gzipped file? */
356: if (File_DoesFileExtensionMatch(pszFileName, ".gz"))
357: {
358: gzFile *hGzFile;
359: /* Create a gzipped file: */
360: hGzFile = gzopen(pszFileName, "wb");
361: if (hGzFile != NULL)
362: {
363: /* Write data, set success flag */
1.1.1.8 root 364: if (gzwrite(hGzFile, pAddress, Size) == (int)Size)
1.1.1.6 root 365: bRet = TRUE;
1.1 root 366:
1.1.1.6 root 367: gzclose(hGzFile);
368: }
369: }
370: else
371: {
1.1.1.9 ! root 372: FILE *hDiskFile;
1.1.1.6 root 373: /* Create a normal file: */
1.1.1.9 ! root 374: hDiskFile = fopen(pszFileName, "wb");
! 375: if (hDiskFile != NULL)
1.1.1.6 root 376: {
377: /* Write data, set success flag */
1.1.1.9 ! root 378: if (fwrite(pAddress, 1, Size, hDiskFile) == Size)
1.1.1.6 root 379: bRet = TRUE;
380:
1.1.1.9 ! root 381: fclose(hDiskFile);
1.1.1.6 root 382: }
1.1 root 383: }
384:
385: return(bRet);
386: }
387:
1.1.1.2 root 388:
389: /*-----------------------------------------------------------------------*/
1.1 root 390: /*
391: Return size of file, -1 if error
392: */
1.1.1.8 root 393: int File_Length(const char *pszFileName)
1.1 root 394: {
1.1.1.9 ! root 395: FILE *hDiskFile;
1.1 root 396: int FileSize;
1.1.1.9 ! root 397:
! 398: hDiskFile = fopen(pszFileName, "rb");
! 399: if (hDiskFile!=NULL)
1.1.1.8 root 400: {
1.1.1.9 ! root 401: fseek(hDiskFile, 0, SEEK_END);
! 402: FileSize = ftell(hDiskFile);
! 403: fseek(hDiskFile, 0, SEEK_SET);
! 404: fclose(hDiskFile);
1.1 root 405: return(FileSize);
406: }
407:
408: return(-1);
409: }
410:
1.1.1.2 root 411:
412: /*-----------------------------------------------------------------------*/
1.1 root 413: /*
414: Return TRUE if file exists
415: */
1.1.1.8 root 416: BOOL File_Exists(const char *pszFileName)
1.1 root 417: {
1.1.1.9 ! root 418: FILE *hDiskFile;
1.1 root 419:
1.1.1.2 root 420: /* Attempt to open file */
1.1.1.9 ! root 421: hDiskFile = fopen(pszFileName, "rb");
! 422: if (hDiskFile!=NULL)
1.1.1.8 root 423: {
1.1.1.9 ! root 424: fclose(hDiskFile);
1.1 root 425: return(TRUE);
1.1.1.2 root 426: }
1.1 root 427: return(FALSE);
428: }
429:
1.1.1.2 root 430:
431: /*-----------------------------------------------------------------------*/
1.1 root 432: /*
433: Find if file exists, and if so ask user if OK to overwrite
434: */
1.1.1.8 root 435: BOOL File_QueryOverwrite(const char *pszFileName)
1.1 root 436: {
1.1.1.7 root 437: char szString[FILENAME_MAX + 26];
1.1 root 438:
1.1.1.2 root 439: /* Try and find if file exists */
1.1.1.6 root 440: if (File_Exists(pszFileName))
441: {
1.1.1.2 root 442: /* File does exist, are we OK to overwrite? */
1.1.1.7 root 443: snprintf(szString, sizeof(szString), "File '%s' exists, overwrite?", pszFileName);
444: fprintf(stderr, "%s\n", szString);
445: return DlgAlert_Query(szString);
1.1 root 446: }
447:
448: return(TRUE);
449: }
450:
1.1.1.2 root 451:
452: /*-----------------------------------------------------------------------*/
1.1 root 453: /*
454: Try filename with various extensions and check if file exists - if so return correct name
455: */
1.1.1.8 root 456: BOOL File_FindPossibleExtFileName(char *pszFileName, const char *ppszExts[])
1.1 root 457: {
1.1.1.8 root 458: char *szSrcDir, *szSrcName, *szSrcExt;
459: char *szTempFileName;
460: int i = 0;
461: BOOL bFileExists = FALSE;
462:
463: /* Allocate temporary memory for strings: */
464: szTempFileName = malloc(4 * FILENAME_MAX);
465: if (!szTempFileName)
466: {
467: perror("File_FindPossibleExtFileName");
468: return FALSE;
469: }
470: szSrcDir = szTempFileName + FILENAME_MAX;
471: szSrcName = szSrcDir + FILENAME_MAX;
472: szSrcExt = szSrcName + FILENAME_MAX;
1.1 root 473:
1.1.1.3 root 474: /* Split filename into parts */
475: File_splitpath(pszFileName, szSrcDir, szSrcName, szSrcExt);
1.1 root 476:
1.1.1.3 root 477: /* Scan possible extensions */
1.1.1.8 root 478: while(ppszExts[i] && !bFileExists)
479: {
1.1.1.3 root 480: /* Re-build with new file extension */
481: File_makepath(szTempFileName, szSrcDir, szSrcName, ppszExts[i]);
482: /* Does this file exist? */
1.1.1.8 root 483: if (File_Exists(szTempFileName))
484: {
1.1.1.3 root 485: /* Copy name for return */
1.1.1.8 root 486: strcpy(pszFileName, szTempFileName);
487: bFileExists = TRUE;
1.1 root 488: }
489:
1.1.1.3 root 490: /* Next one */
1.1 root 491: i++;
492: }
1.1.1.3 root 493:
1.1.1.8 root 494: free(szTempFileName);
495:
496: return bFileExists;
1.1 root 497: }
1.1.1.3 root 498:
499:
500: /*-----------------------------------------------------------------------*/
501: /*
502: Split a complete filename into path, filename and extension.
503: If pExt is NULL, don't split the extension from the file name!
504: */
1.1.1.8 root 505: void File_splitpath(const char *pSrcFileName, char *pDir, char *pName, char *pExt)
1.1.1.3 root 506: {
507: char *ptr1, *ptr2;
508:
509: /* Build pathname: */
510: ptr1 = strrchr(pSrcFileName, '/');
511: if( ptr1 )
512: {
513: strcpy(pDir, pSrcFileName);
514: strcpy(pName, ptr1+1);
515: pDir[ptr1-pSrcFileName+1] = 0;
516: }
517: else
518: {
519: strcpy(pDir, "./");
520: strcpy(pName, pSrcFileName);
521: }
522:
523: /* Build the raw filename: */
524: if( pExt!=NULL )
525: {
526: ptr2 = strrchr(pName+1, '.');
527: if( ptr2 )
528: {
529: pName[ptr2-pName] = 0;
530: /* Copy the file extension: */
531: strcpy(pExt, ptr2+1);
532: }
533: else
534: pExt[0] = 0;
535: }
536: }
537:
538:
539: /*-----------------------------------------------------------------------*/
540: /*
541: Build a complete filename from path, filename and extension.
542: pExt can also be NULL.
543: */
1.1.1.8 root 544: void File_makepath(char *pDestFileName, const char *pDir, const char *pName, const char *pExt)
1.1.1.3 root 545: {
546: strcpy(pDestFileName, pDir);
547: if( strlen(pDestFileName)==0 )
548: strcpy(pDestFileName, "./");
549: if( pDestFileName[strlen(pDestFileName)-1]!='/' )
550: strcat(pDestFileName, "/");
551:
552: strcat(pDestFileName, pName);
553:
554: if( pExt!=NULL )
555: {
556: if( strlen(pExt)>0 && pExt[0]!='.' )
557: strcat(pDestFileName, ".");
558: strcat(pDestFileName, pExt);
559: }
560: }
561:
562:
563: /*-----------------------------------------------------------------------*/
564: /*
565: Shrink a file name to a certain length and insert some dots if we cut
566: something away (usefull for showing file names in a dialog).
567: */
568: void File_ShrinkName(char *pDestFileName, char *pSrcFileName, int maxlen)
569: {
570: int srclen = strlen(pSrcFileName);
571: if( srclen<maxlen )
572: strcpy(pDestFileName, pSrcFileName); /* It fits! */
573: else
574: {
575: strncpy(pDestFileName, pSrcFileName, maxlen/2);
576: if(maxlen&1) /* even or uneven? */
577: pDestFileName[maxlen/2-1] = 0;
578: else
579: pDestFileName[maxlen/2-2] = 0;
580: strcat(pDestFileName, "...");
581: strcat(pDestFileName, &pSrcFileName[strlen(pSrcFileName)-maxlen/2+1]);
582: }
583: }
584:
1.1.1.6 root 585:
586: /*-----------------------------------------------------------------------*/
587: /*
588: Create a clean absolute file name from a (possibly) relative file name.
589: I.e. filter out all occurancies of "./" and "../".
590: pFileName needs to point to a buffer of at least FILENAME_MAX bytes.
591: */
592: void File_MakeAbsoluteName(char *pFileName)
593: {
1.1.1.8 root 594: char *pTempName;
1.1.1.6 root 595: int inpos, outpos;
596:
597: inpos = 0;
1.1.1.8 root 598: pTempName = malloc(FILENAME_MAX);
599: if (!pTempName)
600: {
601: perror("File_MakeAbsoluteName - malloc");
602: return;
603: }
1.1.1.6 root 604:
605: /* Is it already an absolute name? */
606: if(pFileName[0] == '/')
607: {
608: outpos = 0;
609: }
610: else
611: {
1.1.1.8 root 612: if (!getcwd(pTempName, FILENAME_MAX))
613: {
614: perror("File_MakeAbsoluteName - getcwd");
615: free(pTempName);
616: return;
617: }
1.1.1.6 root 618: File_AddSlashToEndFileName(pTempName);
619: outpos = strlen(pTempName);
620: }
621:
622: /* Now filter out the relative paths "./" and "../" */
623: while (pFileName[inpos] != 0 && outpos < FILENAME_MAX)
624: {
625: if (pFileName[inpos] == '.' && pFileName[inpos+1] == '/')
626: {
627: /* Ignore "./" */
628: inpos += 2;
629: }
630: else if (pFileName[inpos] == '.' && pFileName[inpos+1] == '.' && pFileName[inpos+2] == '/')
631: {
632: /* Handle "../" */
633: char *pSlashPos;
634: inpos += 3;
635: pTempName[outpos - 1] = 0;
636: pSlashPos = strrchr(pTempName, '/');
637: if (pSlashPos)
638: {
639: *(pSlashPos + 1) = 0;
640: outpos = strlen(pTempName);
641: }
642: else
643: {
644: pTempName[0] = '/';
645: outpos = 1;
646: }
647: }
648: else
649: {
650: /* Copy until next slash or end of input string */
651: while (pFileName[inpos] != 0 && outpos < FILENAME_MAX)
652: {
653: pTempName[outpos++] = pFileName[inpos++];
654: if (pFileName[inpos - 1] == '/') break;
655: }
656: }
657: }
658:
659: pTempName[outpos] = 0;
660:
661: strcpy(pFileName, pTempName); /* Copy back */
1.1.1.8 root 662: free(pTempName);
663: }
664:
665:
666: /*-----------------------------------------------------------------------*/
667: /*
668: Create a valid path name from a possibly invalid name by erasing invalid
669: path parts at the end of the string.
670: pPathName needs to point to a buffer of at least FILENAME_MAX bytes.
671: */
672: void File_MakeValidPathName(char *pPathName)
673: {
674: struct stat dirstat;
675: char *pLastSlash;
676:
677: do
678: {
679: /* Check for a valid path */
680: if (stat(pPathName, &dirstat) == 0 && S_ISDIR(dirstat.st_mode))
681: {
682: break;
683: }
684:
685: pLastSlash = strrchr(pPathName, '/');
686: if (pLastSlash)
687: {
688: /* Erase the (probably invalid) part after the last slash */
689: *pLastSlash = 0;
690: }
691: else
692: {
693: /* Path name seems to be completely invalid -> set to root directory */
694: strcpy(pPathName, "/");
695: }
696: }
697: while (pLastSlash);
1.1.1.6 root 698: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.