home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / amiga / amidos.c next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  9.6 KB  |  470 lines

  1. /*    SCCS Id: @(#)amidos.c     3.1    93/01/08
  2. /* Copyright (c) Olaf Seibert, Nijmegen, The Netherlands, 1988,1990.    */
  3. /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991, 1992, 1993.  */
  4. /* NetHack may be freely redistributed.  See license for details.    */
  5.  
  6. /*
  7.  * An assortment of imitations of cheap plastic MSDOS and Unix functions.
  8.  */
  9.  
  10. #include "hack.h"
  11. #include "winami.h"
  12.  
  13. /* Defined in config.h, let's undefine it here (static function below) */
  14. #undef strcmpi
  15.  
  16. #include <libraries/dos.h>
  17. #include <exec/execbase.h>
  18. #include <intuition/intuition.h>
  19.  
  20. #undef COUNT
  21. #ifdef LATTICE
  22. # include <proto/exec.h>
  23. # include <proto/dos.h>
  24. #endif
  25.  
  26. #ifdef AZTEC_50
  27. # include <functions.h>
  28. # undef strcmpi
  29. #endif
  30.  
  31. /* Prototypes */
  32. #include "Amiga:winami.p"
  33. #include "Amiga:amiwind.p"
  34. #include "Amiga:amidos.p"
  35.  
  36. extern char Initialized;
  37.  
  38. #ifndef __SASC
  39. int Enable_Abort = 0;   /* for stdio package */
  40. #endif
  41.  
  42. /* Initial path, so we can find NetHack.cnf */
  43. char PATH[PATHLEN] = "Ram:;df0:;NetHack:";
  44.  
  45. static boolean record_exists(void);
  46.  
  47. void
  48. flushout()
  49. {
  50.     (void) fflush(stdout);
  51. }
  52.  
  53. #ifndef getuid
  54. getuid()
  55. {
  56.     return 1;
  57. }
  58. #endif
  59.  
  60. #ifndef getlogin
  61. char *
  62. getlogin()
  63. {
  64.     return ((char *) NULL);
  65. }
  66. #endif
  67.  
  68. #ifndef AZTEC_50
  69. int
  70. abs(x)
  71. int x;
  72. {
  73.     return x < 0? -x: x;
  74. }
  75. #endif
  76.  
  77. #ifdef SHELL
  78. int
  79. dosh()
  80. {
  81.     int i;
  82.     char buf[ 500 ];
  83.     extern struct ExecBase *SysBase;
  84.  
  85.     /* Only under 2.0 and later ROMs do we have System() */
  86.     if( SysBase->LibNode.lib_Version >= 37 )
  87.     {
  88.     getlin("Enter CLI Command...", buf );
  89.     i = System( buf, NULL );
  90.     }
  91.     else
  92.     {
  93.     i = 0;
  94.     pline("No mysterious force prevented you from using multitasking.");
  95.     }
  96.     return i;
  97. }
  98. #endif /* SHELL */
  99.  
  100. #ifdef MFLOPPY
  101. # include <ctype.h>
  102.  
  103. # define Sprintf (void) sprintf
  104.  
  105. #define EXTENSION   72
  106.  
  107. /*
  108.  *  This routine uses an approximation of the free bytes on a disk.
  109.  *  How large a file you can actually write depends on the number of
  110.  *  extension blocks you need for it.
  111.  *  In each extenstion block there are maximum 72 pointers to blocks,
  112.  *  so every 73 disk blocks have only 72 available for data.
  113.  *  The (necessary) file header is also good for 72 data block pointers.
  114.  */
  115. /* TODO: update this for FFS */
  116. long
  117. freediskspace(path)
  118. char *path;
  119. {
  120.     register long freeBytes = 0;
  121.     register struct InfoData *infoData; /* Remember... longword aligned */
  122.     char fileName[32];
  123.  
  124.     /*
  125.      *  Find a valid path on the device of which we want the free space.
  126.      *  If there is a colon in the name, it is an absolute path
  127.      *  and all up to the colon is everything we need.
  128.      *  Remember slashes in a volume name are allowed!
  129.      *  If there is no colon, it is relative to the current directory,
  130.      *  so must be on the current device, so "" is enough...
  131.      */
  132.     {
  133.     register char *colon;
  134.  
  135.     strncpy(fileName, path, sizeof(fileName) - 1);
  136.     fileName[31] = 0;
  137.     if (colon = index(fileName, ':'))
  138.     colon[1] = '\0';
  139.     else
  140.     fileName[0] = '\0';
  141.     }
  142.     {
  143.     BPTR fileLock;
  144.     infoData = (struct InfoData *) alloc(sizeof(struct InfoData));
  145.     if (fileLock = Lock(fileName, SHARED_LOCK)) {
  146.     if (Info(fileLock, infoData)) {
  147.         /* We got a kind of DOS volume, since we can Lock it. */
  148.         /* Calculate number of blocks available for new file */
  149.         /* Kludge for the ever-full VOID: (oops RAM:) device */
  150.         if (infoData->id_UnitNumber == -1 &&
  151.           infoData->id_NumBlocks == infoData->id_NumBlocksUsed) {
  152.         freeBytes = AvailMem(0L) - 64 * 1024L;
  153.             /* Just a stupid guess at the */
  154.             /* Ram-Handler overhead per block: */
  155.         freeBytes -= freeBytes/16;
  156.         } else {
  157.         /* Normal kind of DOS file system device/volume */
  158.         freeBytes = infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
  159.         freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
  160.         freeBytes *= infoData->id_BytesPerBlock;
  161.         }
  162.         if (freeBytes < 0)
  163.         freeBytes = 0;
  164.     }
  165.     UnLock(fileLock);
  166.     }
  167.     free(infoData);
  168.     return freeBytes;
  169.     }
  170. }
  171.  
  172.  
  173. long
  174. filesize(file)
  175. char *file;
  176. {
  177.     register BPTR fileLock;
  178.     register struct FileInfoBlock *fileInfoBlock;
  179.     register long size = 0;
  180.  
  181.     fileInfoBlock = (struct FileInfoBlock *)alloc(sizeof(struct FileInfoBlock));
  182.     if (fileLock = Lock(file, SHARED_LOCK)) {
  183.     if (Examine(fileLock, fileInfoBlock)) {
  184.         size = fileInfoBlock->fib_Size;
  185.     }
  186.     UnLock(fileLock);
  187.     }
  188.     free(fileInfoBlock);
  189.     return size;
  190. }
  191.  
  192. void
  193. eraseall(path, files)
  194. const char *path, *files;
  195. {
  196.     char buf[FILENAME];
  197.     short i;
  198.     BPTR fileLock, dirLock, dirLock2;
  199.     struct FileInfoBlock *fibp;
  200.     int chklen;
  201. #ifdef BETA
  202.     if(files != alllevels)panic("eraseall");
  203. #endif
  204.     chklen=(int)index(files,'*')-(int)files;
  205.  
  206.     if (dirLock = Lock(path ,SHARED_LOCK)) {
  207.     dirLock2=DupLock(dirLock);
  208.     dirLock2= CurrentDir(dirLock2);
  209.     fibp=AllocMem(sizeof(struct FileInfoBlock),0);
  210.     if(fibp){
  211.         if(Examine(dirLock,fibp)){
  212.         while(ExNext(dirLock,fibp)){
  213.             if(!strncmp(fibp->fib_FileName,files,chklen)){
  214.             DeleteFile(fibp->fib_FileName);
  215.             }
  216.         }
  217.         }
  218.         FreeMem(fibp,sizeof(struct FileInfoBlock));
  219.     }
  220.     UnLock(dirLock);
  221.     UnLock(CurrentDir(dirLock2));
  222.     }
  223. }
  224.  
  225. /* This size makes that most files can be copied with two Read()/Write()s */
  226.  
  227. #define COPYSIZE    4096
  228.  
  229. char *CopyFile(from, to)
  230. const char *from, *to;
  231. {
  232.     register BPTR fromFile, toFile;
  233.     register char *buffer;
  234.     register long size;
  235.     char *error = NULL;
  236.  
  237.     buffer = (char *) alloc(COPYSIZE);
  238.     if (fromFile = Open(from, MODE_OLDFILE)) {
  239.     if (toFile = Open(to, MODE_NEWFILE)) {
  240.         while (size = Read(fromFile, buffer, (long)COPYSIZE)) {
  241.         if (size == -1){
  242.             error = "Read error";
  243.             break;
  244.         }
  245.         if (size != Write(toFile, buffer, size)) {
  246.             error = "Write error";
  247.             break;
  248.         }
  249.         }
  250.         Close(toFile);
  251.     } else
  252.         error = "Cannot open destination";
  253.     Close(fromFile);
  254.     } else
  255.     error = "Cannot open source (this should not occur)";
  256.     free(buffer);
  257.     return error;
  258. }
  259.  
  260.  
  261. /* this should be replaced */
  262. saveDiskPrompt(start)
  263. {
  264.     extern int saveprompt;
  265.     char buf[BUFSIZ], *bp;
  266.     BPTR fileLock;
  267.  
  268.     if (saveprompt) {
  269.         /* Don't prompt if you can find the save file */
  270.     if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
  271.         UnLock(fileLock);
  272.         clear_nhwindow( WIN_BASE );
  273.         return 1;
  274.     }
  275.     pline( "If save file is on a SAVE disk, put that disk in now." );
  276.     if( strlen( SAVEF ) > QBUFSZ - 25 - 22 )
  277.         panic( "not enough buffer space for prompt" );
  278.     getlind("File name ?", buf, SAVEF);
  279.     clear_nhwindow( WIN_BASE );
  280.     if (!start && *buf == '\033')
  281.         return 0;
  282.  
  283.     /* Strip any whitespace. Also, if nothing was entered except
  284.      * whitespace, do not change the value of SAVEF.
  285.      */
  286.     for (bp = buf; *bp; bp++) {
  287.         if (!isspace(*bp)) {
  288.         strncpy(SAVEF, bp, PATHLEN);
  289.         break;
  290.         }
  291.     }
  292.     }
  293.     return 1;
  294. }
  295.  
  296. /* Return 1 if the record file was found */
  297. static boolean
  298. record_exists()
  299. {
  300.     FILE *file;
  301.  
  302.     if (file = fopenp(RECORD, "r")) {
  303.     fclose(file);
  304.     return TRUE;
  305.     }
  306.     return FALSE;
  307. }
  308.  
  309. #ifdef MFLOPPY
  310. /*
  311.  * Under MSDOS: Prompt for game disk, then check for record file.
  312.  * For Amiga: do nothing, but called from restore.c
  313.  */
  314. void
  315. gameDiskPrompt(){}
  316. #endif
  317.  
  318. /*
  319.  * Add a slash to any name not ending in / or :.  There must
  320.  * be room for the /.
  321.  */
  322. void
  323. append_slash(name)
  324. char *name;
  325. {
  326.     char *ptr;
  327.  
  328.     if (!*name)return;
  329.  
  330.     ptr = eos(name) - 1;
  331.     if (*ptr != '/' && *ptr != ':') {
  332.     *++ptr = '/';
  333.     *++ptr = '\0';
  334.     }
  335. }
  336.  
  337.  
  338. void
  339. getreturn(str)
  340. const char *str;
  341. {
  342.     int ch;
  343.  
  344.     raw_printf("Hit <RETURN> %s.", str);
  345.     while ((ch = nhgetch()) != '\n' && ch != '\r' )
  346.     continue;
  347. }
  348.  
  349. /* Follow the PATH, trying to fopen the file.
  350.  */
  351. #define PATHSEP    ';'
  352.  
  353. FILE *
  354. fopenp(name, mode)
  355. register const char *name, *mode;
  356. {
  357.     register char *bp, *pp, lastch;
  358.     register FILE *fp;
  359.     register BPTR theLock;
  360.     char buf[BUFSIZ];
  361.  
  362.     /* Try the default directory first.  Then look along PATH.
  363.      */
  364.     strcpy(buf, name);
  365.     if (theLock = Lock(buf, SHARED_LOCK)) {
  366.     UnLock(theLock);
  367.     if (fp = fopen(buf, mode))
  368.         return fp;
  369.     }
  370.     pp = PATH;
  371.     while (pp && *pp) {
  372.     bp = buf;
  373.     while (*pp && *pp != PATHSEP){
  374.         if( bp > buf + BUFSIZ - 1 ) return( NULL );
  375.         lastch = *bp++ = *pp++;
  376.     }
  377.     if (lastch != ':' && lastch != '/' && bp != buf)
  378.         *bp++ = '/';
  379.     strcpy(bp, name);
  380.     if (theLock = Lock(buf, SHARED_LOCK)) {
  381.         UnLock(theLock);
  382.         if (fp = fopen(buf, mode)) return fp;
  383.     }
  384.     if (*pp)
  385.         pp++;
  386.     }
  387.     return NULL;
  388. }
  389. #endif /* MFLOPPY */
  390.  
  391. #ifdef CHDIR
  392.  
  393. /*
  394.  *  A not general-purpose directory changing routine.
  395.  *  Assumes you want to return to the original directory eventually,
  396.  *  by chdir()ing to orgdir.
  397.  *  Assumes -1 is not a valid lock, since 0 is valid.
  398.  */
  399.  
  400. #define NO_LOCK     ((BPTR) -1)
  401.  
  402. char orgdir[1];
  403. static BPTR OrgDirLock = NO_LOCK;
  404.  
  405. chdir(dir)
  406. char *dir;
  407. {
  408.     if (dir == orgdir) {
  409.         /* We want to go back to where we came from. */
  410.     if (OrgDirLock != NO_LOCK) {
  411.         UnLock(CurrentDir(OrgDirLock));
  412.         OrgDirLock = NO_LOCK;
  413.     }
  414.     } else {
  415.         /*
  416.          * Go to some new place. If still at the original
  417.          * directory, save the FileLock.
  418.          */
  419.     BPTR newDir;
  420.  
  421.     if (newDir = Lock(dir, SHARED_LOCK)) {
  422.         if (OrgDirLock == NO_LOCK) {
  423.         OrgDirLock = CurrentDir(newDir);
  424.         } else {
  425.         UnLock(CurrentDir(newDir));
  426.         }
  427.     } else {
  428.         return -1;  /* Failed */
  429.     }
  430.     }
  431.     /* CurrentDir always succeeds if you have a lock */
  432.     return 0;
  433. }
  434.  
  435. #endif /* CHDIR */
  436.  
  437. /* Chdir back to original directory
  438.  */
  439. #undef exit
  440. void
  441. msexit(code)
  442. {
  443. #ifdef CHDIR
  444.     extern char orgdir[];
  445. #endif
  446.  
  447. #ifdef CHDIR
  448.     chdir(orgdir);      /* chdir, not chdirx */
  449. #endif
  450.  
  451.     CleanUp();
  452.     exit(code);
  453. }
  454.  
  455. int
  456. uptodate(fd)
  457. {
  458.     return(1);
  459. }
  460.  
  461. void
  462. regularize(s)    /* normalize file name - we don't like :'s or /'s */
  463. register char *s;
  464. {
  465.     register char *lp;
  466.  
  467.     while((lp = index(s, ':')) || (lp = index(s, '/')))
  468.     *lp = '_';
  469. }
  470.