Annotation of frontvm/hardware/file.c, revision 1.1

1.1     ! root        1: /*
        !             2:   Hatari
        !             3: 
        !             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: 
        !             7:   common file access
        !             8: */
        !             9: 
        !            10: #include <sys/types.h>
        !            11: #include <sys/stat.h>
        !            12: #include <fcntl.h>
        !            13: 
        !            14: #include "main.h"
        !            15: #include "file.h"
        !            16: #include "memAlloc.h"
        !            17: #include "misc.h"
        !            18: 
        !            19: 
        !            20: 
        !            21: #ifdef __BEOS__
        !            22: /* The scandir() and alphasort() functions aren't available on BeOS, */
        !            23: /* so let's declare them here... */
        !            24: #include <dirent.h>
        !            25: 
        !            26: #undef DIRSIZ
        !            27: 
        !            28: #define DIRSIZ(dp)                                          \
        !            29:         ((sizeof(struct dirent) - sizeof(dp)->d_name) +     \
        !            30:                (((dp)->d_reclen + 1 + 3) &~ 3))
        !            31: 
        !            32: 
        !            33: /*-----------------------------------------------------------------------*/
        !            34: /*
        !            35:   Alphabetic order comparison routine for those who want it.
        !            36: */
        !            37: int alphasort(const void *d1, const void *d2)
        !            38: {
        !            39:   return(strcmp((*(struct dirent **)d1)->d_name, (*(struct dirent **)d2)->d_name));
        !            40: }
        !            41: 
        !            42: 
        !            43: /*-----------------------------------------------------------------------*/
        !            44: /*
        !            45:   Scan a directory for all its entries
        !            46: */
        !            47: int scandir(const char *dirname,struct dirent ***namelist, int(*select) __P((struct dirent *)), int (*dcomp) __P((const void *, const void *)))
        !            48: {
        !            49:   register struct dirent *d, *p, **names;
        !            50:   register size_t nitems;
        !            51:   struct stat stb;
        !            52:   long arraysz;
        !            53:   DIR *dirp;
        !            54: 
        !            55:   if ((dirp = opendir(dirname)) == NULL)
        !            56:     return(-1);
        !            57: 
        !            58:   if (fstat(dirp->fd, &stb) < 0)
        !            59:     return(-1);
        !            60: 
        !            61:   /*
        !            62:    * estimate the array size by taking the size of the directory file
        !            63:    * and dividing it by a multiple of the minimum size entry.
        !            64:    */
        !            65:   arraysz = (stb.st_size / 24);
        !            66: 
        !            67:   names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
        !            68:   if (names == NULL)
        !            69:     return(-1);
        !            70: 
        !            71:   nitems = 0;
        !            72: 
        !            73:   while ((d = readdir(dirp)) != NULL) {
        !            74: 
        !            75:      if (select != NULL && !(*select)(d))
        !            76:        continue;       /* just selected names */
        !            77: 
        !            78:      /*
        !            79:       * Make a minimum size copy of the data
        !            80:       */
        !            81: 
        !            82:      p = (struct dirent *)malloc(DIRSIZ(d));
        !            83:      if (p == NULL)
        !            84:        return(-1);
        !            85: 
        !            86:      p->d_ino = d->d_ino;
        !            87:      p->d_reclen = d->d_reclen;
        !            88:      /*p->d_namlen = d->d_namlen;*/
        !            89:      bcopy(d->d_name, p->d_name, p->d_reclen + 1);
        !            90: 
        !            91:      /*
        !            92:       * Check to make sure the array has space left and
        !            93:       * realloc the maximum size.
        !            94:       */
        !            95: 
        !            96:      if (++nitems >= arraysz) {
        !            97: 
        !            98:        if (fstat(dirp->fd, &stb) < 0)
        !            99:          return(-1);     /* just might have grown */
        !           100: 
        !           101:        arraysz = stb.st_size / 12;
        !           102: 
        !           103:        names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
        !           104:        if (names == NULL)
        !           105:          return(-1);
        !           106:      }
        !           107: 
        !           108:      names[nitems-1] = p;
        !           109:    }
        !           110: 
        !           111:    closedir(dirp);
        !           112: 
        !           113:    if (nitems && dcomp != NULL)
        !           114:      qsort(names, nitems, sizeof(struct dirent *), dcomp);
        !           115: 
        !           116:    *namelist = names;
        !           117: 
        !           118:    return(nitems);
        !           119: }
        !           120: 
        !           121: 
        !           122: #endif /* __BEOS__ */
        !           123: 
        !           124: 
        !           125: 
        !           126: /*-----------------------------------------------------------------------*/
        !           127: /*
        !           128:   Remove any '/'s from end of filenames, but keeps / intact
        !           129: */
        !           130: void File_CleanFileName(char *pszFileName)
        !           131: {
        !           132:   int len;
        !           133: 
        !           134:   len = strlen(pszFileName);
        !           135: 
        !           136:   /* Security length check: */
        !           137:   if( len>MAX_FILENAME_LENGTH )
        !           138:   {
        !           139:     pszFileName[MAX_FILENAME_LENGTH-1] = 0;
        !           140:     len = MAX_FILENAME_LENGTH;
        !           141:   }
        !           142: 
        !           143:   /* Remove end slash from filename! But / remains! Doh! */
        !           144:   if( len>2 && pszFileName[len-1]=='/' )
        !           145:     pszFileName[len-1] = 0;
        !           146: }
        !           147: 
        !           148: 
        !           149: /*-----------------------------------------------------------------------*/
        !           150: /*
        !           151:   Add '/' to end of filename
        !           152: */
        !           153: void File_AddSlashToEndFileName(char *pszFileName)
        !           154: {
        !           155:   /* Check dir/filenames */
        !           156:   if (strlen(pszFileName)!=0) {
        !           157:     if (pszFileName[strlen(pszFileName)-1]!='/')
        !           158:       strcat(pszFileName,"/");  /* Must use end slash */
        !           159:   }
        !           160: }
        !           161: 
        !           162: 
        !           163: /*-----------------------------------------------------------------------*/
        !           164: /*
        !           165:   Does filename extension match? If so, return TRUE
        !           166: */
        !           167: BOOL File_DoesFileExtensionMatch(char *pszFileName, char *pszExtension)
        !           168: {
        !           169:   if ( strlen(pszFileName) < strlen(pszExtension) )
        !           170:     return(FALSE);
        !           171:   /* Is matching extension? */
        !           172:   if ( !strcasecmp(&pszFileName[strlen(pszFileName)-strlen(pszExtension)], pszExtension) )
        !           173:     return(TRUE);
        !           174: 
        !           175:   /* No */
        !           176:   return(FALSE);
        !           177: }
        !           178: 
        !           179: 
        !           180: /*-----------------------------------------------------------------------*/
        !           181: /*
        !           182:   Check if filename is from root
        !           183:   
        !           184:   Return TRUE if filename is '/', else give FALSE
        !           185: */
        !           186: BOOL File_IsRootFileName(char *pszFileName)
        !           187: {
        !           188:   if (pszFileName[0]=='\0')     /* If NULL string return! */
        !           189:     return(FALSE);
        !           190: 
        !           191:   if (pszFileName[0]=='/')
        !           192:     return(TRUE);
        !           193: 
        !           194:   return(FALSE);
        !           195: }
        !           196: 
        !           197: 
        !           198: /*-----------------------------------------------------------------------*/
        !           199: /*
        !           200:   Return string, to remove 'C:' part of filename
        !           201: */
        !           202: char *File_RemoveFileNameDrive(char *pszFileName)
        !           203: {
        !           204:   if ( (pszFileName[0]!='\0') && (pszFileName[1]==':') )
        !           205:     return(&pszFileName[2]);
        !           206:   else
        !           207:     return(pszFileName);
        !           208: }
        !           209: 
        !           210: 
        !           211: /*-----------------------------------------------------------------------*/
        !           212: /*
        !           213:   Check if filename end with a '/'
        !           214:   
        !           215:   Return TRUE if filename ends with '/'
        !           216: */
        !           217: BOOL File_DoesFileNameEndWithSlash(char *pszFileName)
        !           218: {
        !           219:   if (pszFileName[0]=='\0')    /* If NULL string return! */
        !           220:     return(FALSE);
        !           221: 
        !           222:   /* Does string end in a '/'? */
        !           223:   if (pszFileName[strlen(pszFileName)-1]=='/')
        !           224:     return(TRUE);
        !           225: 
        !           226:   return(FALSE);
        !           227: }
        !           228: 
        !           229: 
        !           230: /*-----------------------------------------------------------------------*/
        !           231: /*
        !           232:   Remove any double '/'s  from end of filenames. So just the one
        !           233: */
        !           234: void File_RemoveFileNameTrailingSlashes(char *pszFileName)
        !           235: {
        !           236:   int Length;
        !           237: 
        !           238:   /* Do have slash at end of filename? */
        !           239:   Length = strlen(pszFileName);
        !           240:   if (Length>=3) {
        !           241:     if (pszFileName[Length-1]=='/') {     /* Yes, have one previous? */
        !           242:       if (pszFileName[Length-2]=='/')
        !           243:         pszFileName[Length-1] = '\0';     /* then remove it! */
        !           244:     }
        !           245:   }
        !           246: }
        !           247: 
        !           248: 
        !           249: /*-----------------------------------------------------------------------*/
        !           250: /*
        !           251:   Does filename end with a .ST.GZ extension? If so, return TRUE
        !           252: */
        !           253: BOOL File_FileNameIsSTGZ(char *pszFileName)
        !           254: {
        !           255:   return(File_DoesFileExtensionMatch(pszFileName,".st.gz"));
        !           256: }
        !           257: 
        !           258: 
        !           259: /*-----------------------------------------------------------------------*/
        !           260: /*
        !           261:   Does filename end with a .MSA.GZ extension? If so, return TRUE
        !           262: */
        !           263: BOOL File_FileNameIsMSAGZ(char *pszFileName)
        !           264: {
        !           265:   return(File_DoesFileExtensionMatch(pszFileName,".msa.gz"));
        !           266: }
        !           267: 
        !           268: 
        !           269: /*-----------------------------------------------------------------------*/
        !           270: /*
        !           271:   Does filename end with a .ZIP extension? If so, return TRUE
        !           272: */
        !           273: BOOL File_FileNameIsZIP(char *pszFileName)
        !           274: {
        !           275:   return(File_DoesFileExtensionMatch(pszFileName,".zip"));
        !           276: }
        !           277: 
        !           278: 
        !           279: /*-----------------------------------------------------------------------*/
        !           280: /*
        !           281:   Does filename end with a .MSA extension? If so, return TRUE
        !           282: */
        !           283: BOOL File_FileNameIsMSA(char *pszFileName)
        !           284: {
        !           285:   return(File_DoesFileExtensionMatch(pszFileName,".msa"));
        !           286: }
        !           287: 
        !           288: 
        !           289: /*-----------------------------------------------------------------------*/
        !           290: /*
        !           291:   Does filename end with a .ST extension? If so, return TRUE
        !           292: */
        !           293: BOOL File_FileNameIsST(char *pszFileName)
        !           294: {
        !           295:   return(File_DoesFileExtensionMatch(pszFileName,".st"));
        !           296: }
        !           297: 
        !           298: 
        !           299: /*-----------------------------------------------------------------------*/
        !           300: /*
        !           301:   Read file from PC into memory, allocate memory for it if need to (pass Address as NULL)
        !           302:   Also may pass 'unsigned long' if want to find size of file read (may pass as NULL)
        !           303: */
        !           304: void *File_Read(char *pszFileName, void *pAddress, long *pFileSize, char *ppszExts[])
        !           305: {
        !           306:   FILE *DiscFile;
        !           307:   void *pFile=NULL;
        !           308:   long FileSize=0;
        !           309: 
        !           310:   /* Does the file exist? If not, see if can scan for other extensions and try these */
        !           311:   if (!File_Exists(pszFileName) && ppszExts) {
        !           312:     /* Try other extensions, if suceeds correct filename is now in 'pszFileName' */
        !           313:     File_FindPossibleExtFileName(pszFileName,ppszExts);
        !           314:   }
        !           315: 
        !           316:   /* Open our file */
        !           317:   DiscFile = fopen(pszFileName, "rb");
        !           318:   if (DiscFile!=NULL) {
        !           319:     /* Find size of TOS image - 192k or 256k */
        !           320:     fseek(DiscFile, 0, SEEK_END);
        !           321:     FileSize = ftell(DiscFile);
        !           322:     fseek(DiscFile, 0, SEEK_SET);
        !           323:     /* Find pointer to where to load, allocate memory if pass NULL */
        !           324:     if (pAddress)
        !           325:       pFile = pAddress;
        !           326:     else
        !           327:       pFile = Memory_Alloc(FileSize);
        !           328:     /* Read in... */
        !           329:     if (pFile)
        !           330:       fread((char *)pFile, 1, FileSize, DiscFile);
        !           331: 
        !           332:     fclose(DiscFile);
        !           333:   }
        !           334:   /* Store size of file we read in (or 0 if failed) */
        !           335:   if (pFileSize)
        !           336:     *pFileSize = FileSize;
        !           337: 
        !           338:   return(pFile);        /* Return to where read in/allocated */
        !           339: }
        !           340: 
        !           341: 
        !           342: /*-----------------------------------------------------------------------*/
        !           343: /*
        !           344:   Save file to PC, return FALSE if errors
        !           345: */
        !           346: BOOL File_Save(char *pszFileName, void *pAddress,long Size,BOOL bQueryOverwrite)
        !           347: {
        !           348:   FILE *DiscFile;
        !           349:   BOOL bRet=FALSE;
        !           350: 
        !           351:   /* Check if need to ask user if to overwrite */
        !           352:   if (bQueryOverwrite) {
        !           353:     /* If file exists, ask if OK to overwrite */
        !           354:     if (!File_QueryOverwrite(pszFileName))
        !           355:       return(FALSE);
        !           356:   }
        !           357: 
        !           358:   /* Create our file */
        !           359:   DiscFile = fopen(pszFileName, "wb");
        !           360:   if (DiscFile!=NULL) {
        !           361:     /* Write data, set success flag */
        !           362:     if ( fwrite(pAddress, 1, Size, DiscFile)==Size )
        !           363:       bRet = TRUE;
        !           364: 
        !           365:     fclose(DiscFile);
        !           366:   }
        !           367: 
        !           368:   return(bRet);
        !           369: }
        !           370: 
        !           371: 
        !           372: /*-----------------------------------------------------------------------*/
        !           373: /*
        !           374:   Return size of file, -1 if error
        !           375: */
        !           376: int File_Length(char *pszFileName)
        !           377: {
        !           378:   FILE *DiscFile;
        !           379:   int FileSize;
        !           380:   DiscFile = fopen(pszFileName, "rb");
        !           381:   if (DiscFile!=NULL) {
        !           382:     fseek(DiscFile, 0, SEEK_END);
        !           383:     FileSize = ftell(DiscFile);
        !           384:     fseek(DiscFile, 0, SEEK_SET);
        !           385:     fclose(DiscFile);
        !           386:     return(FileSize);
        !           387:   }
        !           388: 
        !           389:   return(-1);
        !           390: }
        !           391: 
        !           392: 
        !           393: /*-----------------------------------------------------------------------*/
        !           394: /*
        !           395:   Return TRUE if file exists
        !           396: */
        !           397: BOOL File_Exists(char *pszFileName)
        !           398: {
        !           399:   FILE *DiscFile;
        !           400: 
        !           401:   /* Attempt to open file */
        !           402:   DiscFile = fopen(pszFileName, "rb");
        !           403:   if (DiscFile!=NULL) {
        !           404:     fclose(DiscFile);
        !           405:     return(TRUE);
        !           406:   }
        !           407:   return(FALSE);
        !           408: }
        !           409: 
        !           410: 
        !           411: /*-----------------------------------------------------------------------*/
        !           412: /*
        !           413:   Delete file, return TRUE if OK
        !           414: */
        !           415: BOOL File_Delete(char *pszFileName)
        !           416: {
        !           417:   /* Delete the file (must be closed first) */
        !           418:   return( remove(pszFileName) );
        !           419: }
        !           420: 
        !           421: 
        !           422: /*-----------------------------------------------------------------------*/
        !           423: /*
        !           424:   Find if file exists, and if so ask user if OK to overwrite
        !           425: */
        !           426: BOOL File_QueryOverwrite(char *pszFileName)
        !           427: {
        !           428: 
        !           429:   char szString[MAX_FILENAME_LENGTH];
        !           430: 
        !           431:   /* Try and find if file exists */
        !           432:   if (File_Exists(pszFileName)) {
        !           433:     /* File does exist, are we OK to overwrite? */
        !           434:     sprintf(szString,"File '%s' exists, overwrite?",pszFileName);
        !           435: /* FIXME: */
        !           436: //    if (MessageBox(hWnd,szString,PROG_NAME,MB_YESNO | MB_DEFBUTTON2 | MB_ICONSTOP)==IDNO)
        !           437: //      return(FALSE);
        !           438:   }
        !           439: 
        !           440:   return(TRUE);
        !           441: }
        !           442: 
        !           443: 
        !           444: /*-----------------------------------------------------------------------*/
        !           445: /*
        !           446:   Try filename with various extensions and check if file exists - if so return correct name
        !           447: */
        !           448: BOOL File_FindPossibleExtFileName(char *pszFileName, char *ppszExts[])
        !           449: {
        !           450:   char szSrcDir[256], szSrcName[128], szSrcExt[32];
        !           451:   char szTempFileName[MAX_FILENAME_LENGTH];
        !           452:   int i=0;
        !           453: 
        !           454:   /* Split filename into parts */
        !           455:   File_splitpath(pszFileName, szSrcDir, szSrcName, szSrcExt);
        !           456: 
        !           457:   /* Scan possible extensions */
        !           458:   while(ppszExts[i]) {
        !           459:     /* Re-build with new file extension */
        !           460:     File_makepath(szTempFileName, szSrcDir, szSrcName, ppszExts[i]);
        !           461:     /* Does this file exist? */
        !           462:     if (File_Exists(szTempFileName)) {
        !           463:       /* Copy name for return */
        !           464:       strcpy(pszFileName,szTempFileName);
        !           465:       return(TRUE);
        !           466:     }
        !           467: 
        !           468:     /* Next one */
        !           469:     i++;
        !           470:   }
        !           471: 
        !           472:   /* No, none of the files exist */
        !           473:   return(FALSE);
        !           474: }
        !           475: 
        !           476: 
        !           477: /*-----------------------------------------------------------------------*/
        !           478: /*
        !           479:   Split a complete filename into path, filename and extension.
        !           480:   If pExt is NULL, don't split the extension from the file name!
        !           481: */
        !           482: void File_splitpath(char *pSrcFileName, char *pDir, char *pName, char *pExt)
        !           483: {
        !           484:   char *ptr1, *ptr2;
        !           485: 
        !           486:   /* Build pathname: */
        !           487:   ptr1 = strrchr(pSrcFileName, '/');
        !           488:   if( ptr1 )
        !           489:   {
        !           490:     strcpy(pDir, pSrcFileName);
        !           491:     strcpy(pName, ptr1+1);
        !           492:     pDir[ptr1-pSrcFileName+1] = 0;
        !           493:   }
        !           494:   else
        !           495:   {
        !           496:     strcpy(pDir, "./");
        !           497:     strcpy(pName, pSrcFileName);
        !           498:   }
        !           499: 
        !           500:   /* Build the raw filename: */
        !           501:   if( pExt!=NULL )
        !           502:   {
        !           503:     ptr2 = strrchr(pName+1, '.');
        !           504:     if( ptr2 )
        !           505:     {
        !           506:       pName[ptr2-pName] = 0;
        !           507:       /* Copy the file extension: */
        !           508:       strcpy(pExt, ptr2+1);
        !           509:     }
        !           510:     else
        !           511:       pExt[0] = 0;
        !           512:    }
        !           513: }
        !           514: 
        !           515: 
        !           516: /*-----------------------------------------------------------------------*/
        !           517: /*
        !           518:   Build a complete filename from path, filename and extension.
        !           519:   pExt can also be NULL.
        !           520: */
        !           521: void File_makepath(char *pDestFileName, char *pDir, char *pName, char *pExt)
        !           522: {
        !           523:   strcpy(pDestFileName, pDir);
        !           524:   if( strlen(pDestFileName)==0 )
        !           525:     strcpy(pDestFileName, "./");
        !           526:   if( pDestFileName[strlen(pDestFileName)-1]!='/' )
        !           527:     strcat(pDestFileName, "/");
        !           528: 
        !           529:   strcat(pDestFileName, pName);
        !           530: 
        !           531:   if( pExt!=NULL )
        !           532:   {
        !           533:     if( strlen(pExt)>0 && pExt[0]!='.' )
        !           534:       strcat(pDestFileName, ".");
        !           535:     strcat(pDestFileName, pExt);
        !           536:   }
        !           537: }
        !           538: 
        !           539: 
        !           540: /*-----------------------------------------------------------------------*/
        !           541: /*
        !           542:   Shrink a file name to a certain length and insert some dots if we cut
        !           543:   something away (usefull for showing file names in a dialog).
        !           544: */
        !           545: void File_ShrinkName(char *pDestFileName, char *pSrcFileName, int maxlen)
        !           546: {
        !           547:   int srclen = strlen(pSrcFileName);
        !           548:   if( srclen<maxlen )
        !           549:     strcpy(pDestFileName, pSrcFileName);  /* It fits! */
        !           550:   else
        !           551:   {
        !           552:     strncpy(pDestFileName, pSrcFileName, maxlen/2);
        !           553:     if(maxlen&1)  /* even or uneven? */
        !           554:       pDestFileName[maxlen/2-1] = 0;
        !           555:     else
        !           556:       pDestFileName[maxlen/2-2] = 0;
        !           557:     strcat(pDestFileName, "...");
        !           558:     strcat(pDestFileName, &pSrcFileName[strlen(pSrcFileName)-maxlen/2+1]);
        !           559:   }
        !           560: }
        !           561: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.