home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / share / pcsys.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-19  |  8.0 KB  |  445 lines

  1. /*    SCCS Id: @(#)pcsys.c    3.1    93/01/01
  2. /* NetHack may be freely redistributed.  See license for details. */
  3.  
  4. /*
  5.  *  System related functions for MSDOS, OS/2 and TOS
  6.  */
  7.  
  8. #define NEED_VARARGS
  9. #include "hack.h"
  10. #include "wintty.h"
  11.  
  12. #include <ctype.h>
  13. #include <fcntl.h>
  14. #ifndef __GO32__
  15. #include <process.h>
  16. #else
  17. #define P_WAIT          0
  18. #define P_NOWAIT        1
  19. #endif
  20. #ifdef TOS
  21. #include <osbind.h>
  22. #endif
  23.  
  24. static boolean NDECL(record_exists);
  25. #ifndef TOS
  26. static boolean NDECL(comspec_exists);
  27. #endif
  28.  
  29. # ifdef MICRO
  30.  
  31. void
  32. flushout()
  33. {
  34.     (void) fflush(stdout);
  35.     return;
  36. }
  37.  
  38. static const char *COMSPEC = 
  39. #  ifdef TOS
  40. "SHELL";
  41. #  else
  42. "COMSPEC";
  43. #  endif
  44.  
  45. #define getcomspec() getenv(COMSPEC)
  46.  
  47. #  ifdef SHELL
  48. int
  49. dosh()
  50. {
  51.     extern char orgdir[];
  52.     char *comspec;
  53.  
  54.     if (comspec = getcomspec()) {
  55. #   ifndef TOS    /* TOS has a variety of shells */
  56.         suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
  57. #   else
  58.         suspend_nhwindows((char *)0);
  59. #   endif /* TOS */
  60.         chdirx(orgdir, 0);
  61.         if (spawnl(P_WAIT, comspec, comspec, NULL) < 0) {
  62.             raw_printf("Can't spawn \"%s\"!", comspec);
  63.             getreturn("to continue");
  64.         }
  65. #   ifdef TOS
  66. /* Some shells (e.g. Gulam) turn the cursor off when they exit */
  67.         if (flags.BIOS)
  68.             (void)Cursconf(1, -1);
  69. #   endif
  70.         get_scr_size(); /* maybe the screen mode changed (TH) */
  71.         resume_nhwindows();
  72.         chdirx(hackdir, 0);
  73.     } else
  74.         pline("Can't find %s.",COMSPEC);
  75.     return 0;
  76. }
  77. #  endif /* SHELL */
  78.  
  79. #  ifdef MFLOPPY
  80.  
  81. void
  82. eraseall(path, files)
  83. const char *path, *files;
  84. {
  85.     char buf[PATHLEN];
  86.     char *foundfile;
  87.  
  88.     foundfile = foundfile_buffer(); 
  89.         Sprintf(buf, "%s%s", path, files);
  90.     if (findfirst(buf))
  91.         do {
  92.                Sprintf(buf, "%s%s", path, foundfile); 
  93.         (void) unlink(buf);
  94.         } while (findnext());
  95.     return;
  96. }
  97.  
  98. /*
  99.  * Rewritten for version 3.3 to be faster
  100.  */
  101. void
  102. copybones(mode)
  103. int mode;
  104. {
  105.     char from[PATHLEN], to[PATHLEN], last[13];
  106.     char *frompath, *topath;
  107.     char *foundfile;
  108. #  ifndef TOS
  109.     int status;
  110.     char copy[8], *comspec;
  111.     extern saveprompt;
  112. #  endif
  113.  
  114.     if (!ramdisk)
  115.         return;
  116.  
  117.     /* Find the name of the last file to be transferred
  118.      */
  119.     frompath = (mode != TOPERM) ? permbones : levels;
  120.     foundfile = foundfile_buffer();
  121.     last[0] = '\0';
  122.     Sprintf(from, "%s%s", frompath, allbones);
  123.     topath = (mode == TOPERM) ? permbones : levels;
  124. #  ifdef TOS
  125.     eraseall(topath, allbones);
  126. #  endif
  127.     if (findfirst(from))
  128.         do {
  129. #  ifdef TOS
  130.             Sprintf(from, "%s%s", frompath, foundfile); 
  131.             Sprintf(to, "%s%s", topath, foundfile);
  132.             if (_copyfile(from, to))
  133.                 goto error_copying;
  134. #  endif
  135.             Strcpy(last, foundfile);
  136.         } while (findnext());
  137. #  ifdef TOS
  138.     else
  139.         return;
  140. #  else
  141.     if (last[0]) {
  142.         Sprintf(copy, "%cC copy",switchar());
  143.  
  144.         /* Remove any bones files in `to' directory.
  145.          */
  146.         eraseall(topath, allbones);
  147.  
  148.         /* Copy `from' to `to' */
  149.         Sprintf(to, "%s%s", topath, allbones);
  150.         comspec = getcomspec();
  151.         status =spawnl(P_WAIT, comspec, comspec, copy, from,
  152.             to, "> nul", NULL);
  153.     } else
  154.         return;
  155. #  endif /* TOS */
  156.  
  157.     /* See if the last file got there.  If so, remove the ramdisk bones
  158.      * files.
  159.      */
  160.     Sprintf(to, "%s%s", topath, last);
  161.     if (findfirst(to)) {
  162.         if (mode == TOPERM)
  163.             eraseall(frompath, allbones);
  164.         return;
  165.     }
  166.  
  167. #  ifdef TOS
  168. error_copying:
  169. #  endif
  170.     /* Last file didn't get there.
  171.      */
  172.     Sprintf(to, "%s%s", topath, allbones);
  173.     msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
  174. #  ifndef TOS
  175.     if (status < 0)
  176.         msmsg("can't spawn \"%s\"!", comspec);
  177.     else
  178. #  endif
  179.         msmsg((freediskspace(topath) < filesize(from)) ?
  180.             "insufficient disk space." : "bad path(s)?");
  181.     if (mode == TOPERM) {
  182.         msmsg("Bones will be left in \"%s\"\n",
  183.             *levels ? levels : hackdir);
  184.     } else {
  185.         /* Remove all bones files on the RAMdisk */
  186.         eraseall(levels, allbones);
  187.         playwoRAMdisk();
  188.     }
  189.     return;
  190. }
  191.  
  192. void
  193. playwoRAMdisk()
  194. {
  195.     int c;
  196.  
  197.     msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
  198.  
  199.     /* Set ramdisk false *before* exit-ing (because msexit calls
  200.      * copybones)
  201.      */
  202.     ramdisk = FALSE;
  203.     c = tgetch(); if (c == 'Y') c = 'y';
  204.     if (c != 'y') {
  205.         settty("Be seeing you...\n");
  206.         exit(0);
  207.     }
  208.     set_lock_and_bones();
  209.     return;
  210. }
  211.  
  212. int
  213. saveDiskPrompt(start)
  214. int start;
  215. {
  216.     extern saveprompt;
  217.     char buf[BUFSIZ], *bp;
  218.     char qbuf[QBUFSZ];
  219.  
  220.     int fd;
  221.  
  222.     if (saveprompt) {
  223.         /* Don't prompt if you can find the save file */
  224.         if ((fd = open_savefile()) >= 0) {
  225.             (void) close(fd);
  226.             return 1;
  227.         }
  228.         clear_nhwindow(WIN_MESSAGE);
  229.         pline("If save file is on a save disk, insert that disk now.");
  230.         mark_synch();
  231.         Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
  232.             start ? "" : ", <Esc> cancels save");
  233.         getlin(qbuf, buf);
  234.         clear_nhwindow(WIN_MESSAGE);
  235.         if (!start && *buf == '\033')
  236.             return 0;
  237.  
  238.         /* Strip any whitespace. Also, if nothing was entered except
  239.          * whitespace, do not change the value of SAVEF.
  240.          */
  241.         for (bp = buf; *bp; bp++)
  242.             if (!isspace(*bp)) {
  243.                 strncpy(SAVEF, bp, PATHLEN);
  244.                 break;
  245.             }
  246.     }
  247.     return 1;
  248. }
  249.  
  250. #endif /* MFLOPPY */
  251.  
  252. /* Return 1 if the record file was found */
  253. static boolean
  254. record_exists()
  255. {
  256.     FILE *fp;
  257.  
  258.     fp = fopen_datafile(RECORD, "r");
  259.     if (fp) {
  260.         fclose(fp);
  261.         return TRUE;
  262.     }
  263.     return FALSE;
  264. }
  265.  
  266. #  ifdef TOS
  267. #define comspec_exists() 1
  268. #  else
  269. /* Return 1 if the comspec was found */
  270. static boolean
  271. comspec_exists()
  272. {
  273.     int fd;
  274.     char *comspec;
  275.  
  276.     if (comspec = getcomspec())
  277.         if ((fd = open(comspec, O_RDONLY)) >= 0) {
  278.             (void) close(fd);
  279.             return TRUE;
  280.         }
  281.     return FALSE;
  282. }
  283. # endif
  284.  
  285. #ifdef MFLOPPY
  286. /* Prompt for game disk, then check for record file.
  287.  */
  288. void
  289. gameDiskPrompt()
  290. {
  291.     extern int saveprompt;
  292.  
  293.     if (saveprompt) {
  294.         if (record_exists() && comspec_exists())
  295.             return;
  296.         (void) putchar('\n');
  297.         getreturn("when the game disk has been inserted");
  298.     }
  299.     if (comspec_exists() && record_exists())
  300.         return;
  301.  
  302.     if (!comspec_exists())
  303.         msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
  304.         if (!record_exists())
  305.         msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
  306.     msmsg("If the game disk is not in, insert it now.\n");
  307.     getreturn("to continue");
  308.     return;
  309. }
  310. # endif
  311. # endif /* MFLOPPY */
  312.  
  313. /*
  314.  * Add a backslash to any name not ending in /, \ or :   There must
  315.  * be room for the \
  316.  */
  317. void
  318. append_slash(name)
  319. char *name;
  320. {
  321.     char *ptr;
  322.  
  323.     if (!*name)
  324.         return;
  325.     ptr = name + (strlen(name) - 1);
  326.     if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
  327.         *++ptr = '\\';
  328.         *++ptr = '\0';
  329.     }
  330.     return;
  331. }
  332.  
  333. void
  334. getreturn(str)
  335. const char *str;
  336. {
  337. # ifdef TOS
  338.     msmsg("Hit <Return> %s.", str);
  339. # else
  340.     msmsg("Hit <Enter> %s.", str);
  341. # endif
  342.     while (Getchar() != '\n') ;
  343.     return;
  344. }
  345.  
  346. void
  347. msmsg VA_DECL(const char *, fmt)
  348.     VA_START(fmt);
  349.     VA_INIT(fmt, const char *);
  350.     Vprintf(fmt, VA_ARGS);
  351.     flushout();
  352.     VA_END();
  353.     return;
  354. }
  355.  
  356. /*
  357.  * Follow the PATH, trying to fopen the file.
  358.  */
  359. #  ifdef TOS
  360. #   ifdef __MINT__
  361. #define PATHSEP ':'
  362. #   else
  363. #define PATHSEP    ','
  364. #   endif
  365. #  else
  366. #define PATHSEP    ';'
  367. #  endif
  368.  
  369. FILE *
  370. fopenp(name, mode)
  371. const char *name, *mode;
  372. {
  373.     char buf[BUFSIZ], *bp, *pp, lastch = 0;
  374.     FILE *fp;
  375.  
  376.     /* Try the default directory first.  Then look along PATH.
  377.      */
  378.     Strcpy(buf, name);
  379.     if (fp = fopen(buf, mode))
  380.         return fp;
  381.     else {
  382.         pp = getenv("PATH");
  383.         while (pp && *pp) {
  384.             bp = buf;
  385.             while (*pp && *pp != PATHSEP)
  386.                 lastch = *bp++ = *pp++;
  387.             if (lastch != '\\' && lastch != '/')
  388.                 *bp++ = '\\';
  389.             Strcpy(bp, name);
  390.             if (fp = fopen(buf, mode))
  391.                 return fp;
  392.             if (*pp)
  393.                 pp++;
  394.         }
  395.     }
  396. #  ifdef OS2_CODEVIEW /* one more try for hackdir */
  397.     Strcpy(buf,hackdir);
  398.     append_slash(buf);
  399.     Strcat(buf,name);
  400.     if(fp = fopen(buf,mode))
  401.         return fp;
  402. #  endif
  403.     return (FILE *)0;
  404. }
  405.  
  406. /* Chdir back to original directory
  407.  */
  408. #undef exit
  409. # ifdef TOS
  410. extern boolean run_from_desktop;    /* set in pcmain.c */
  411. # endif
  412.  
  413. void exit(int);
  414.  
  415. void
  416. msexit(code)
  417. int code;
  418. {
  419. # ifdef CHDIR
  420.     extern char orgdir[];
  421. # endif
  422.  
  423.     flushout();
  424. # ifndef TOS
  425.     enable_ctrlP();        /* in case this wasn't done */
  426. # endif
  427. # ifdef MFLOPPY
  428.     if (ramdisk) copybones(TOPERM);
  429. # endif
  430. # ifdef CHDIR
  431.     chdir(orgdir);        /* chdir, not chdirx */
  432.     chdrive(orgdir);
  433. # endif
  434. # ifdef TOS
  435.     if (run_from_desktop)
  436.         getreturn("to continue"); /* so the user can read the score list */
  437. #  ifdef TEXTCOLOR
  438.     if (colors_changed)
  439.         restore_colors();
  440. #  endif
  441. # endif
  442.     exit(code);
  443.     return;
  444. }
  445.