1 /* NetHack 3.6 amidos.c $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
2 /* Copyright (c) Olaf Seibert, Nijmegen, The Netherlands, 1988,1990. */
3 /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991,1992,1993,1996. */
4 /* NetHack may be freely redistributed. See license for details. */
7 * An assortment of imitations of cheap plastic MSDOS and Unix functions.
13 /* Defined in config.h, let's undefine it here (static function below) */
16 #include <libraries/dos.h>
17 #include <exec/execbase.h>
18 #include <intuition/intuition.h>
21 #if defined(__SASC_60) || defined(__GNUC__)
22 #include <proto/exec.h>
23 #include <proto/dos.h>
27 #include <functions.h>
32 #include "NH:sys/amiga/winami.p"
33 #include "NH:sys/amiga/amiwind.p"
34 #include "NH:sys/amiga/amidos.p"
36 extern char Initialized;
37 extern struct window_procs amii_procs;
40 int Enable_Abort = 0; /* for stdio package */
43 /* Initial path, so we can find NetHack.cnf */
44 char PATH[PATHLEN] = "NetHack:";
46 static boolean record_exists(void);
51 (void) fflush(stdout);
65 return ((char *) NULL);
74 return x < 0 ? -x : x;
84 extern struct ExecBase *SysBase;
86 /* Only under 2.0 and later ROMs do we have System() */
87 if (SysBase->LibNode.lib_Version >= 37 && !amibbs) {
88 getlin("Enter CLI Command...", buf);
90 i = System(buf, NULL);
93 pline("No mysterious force prevented you from using multitasking.");
102 #define Sprintf (void) sprintf
107 * This routine uses an approximation of the free bytes on a disk.
108 * How large a file you can actually write depends on the number of
109 * extension blocks you need for it.
110 * In each extenstion block there are maximum 72 pointers to blocks,
111 * so every 73 disk blocks have only 72 available for data.
112 * The (necessary) file header is also good for 72 data block pointers.
114 /* TODO: update this for FFS */
120 /* these changes from Patric Mueller <bhaak@gmx.net> for AROS to
121 * handle larger disks. Also needs limits.h and aros/oldprograms.h
124 unsigned long long freeBytes = 0;
126 register long freeBytes = 0;
128 register struct InfoData *infoData; /* Remember... longword aligned */
132 * Find a valid path on the device of which we want the free space.
133 * If there is a colon in the name, it is an absolute path
134 * and all up to the colon is everything we need.
135 * Remember slashes in a volume name are allowed!
136 * If there is no colon, it is relative to the current directory,
137 * so must be on the current device, so "" is enough...
140 register char *colon;
142 strncpy(fileName, path, sizeof(fileName) - 1);
144 if (colon = index(fileName, ':'))
151 infoData = (struct InfoData *) alloc(sizeof(struct InfoData));
152 if (fileLock = Lock(fileName, SHARED_LOCK)) {
153 if (Info(fileLock, infoData)) {
154 /* We got a kind of DOS volume, since we can Lock it. */
155 /* Calculate number of blocks available for new file */
156 /* Kludge for the ever-full VOID: (oops RAM:) device */
157 if (infoData->id_UnitNumber == -1
158 && infoData->id_NumBlocks == infoData->id_NumBlocksUsed) {
159 freeBytes = AvailMem(0L) - 64 * 1024L;
160 /* Just a stupid guess at the */
161 /* Ram-Handler overhead per block: */
162 freeBytes -= freeBytes / 16;
164 /* Normal kind of DOS file system device/volume */
166 infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
167 freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
168 freeBytes *= infoData->id_BytesPerBlock;
170 if (freeBytes > LONG_MAX) {
171 freeBytes = LONG_MAX;
189 register BPTR fileLock;
190 register struct FileInfoBlock *fileInfoBlock;
191 register long size = 0;
194 (struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock));
195 if (fileLock = Lock(file, SHARED_LOCK)) {
196 if (Examine(fileLock, fileInfoBlock)) {
197 size = fileInfoBlock->fib_Size;
207 eraseall(path, files)
208 const char *path, *files;
210 BPTR dirLock, dirLock2;
211 struct FileInfoBlock *fibp;
214 if(files != alllevels)panic("eraseall");
216 chklen=(int)index(files,'*')-(int)files;
218 if (dirLock = Lock( (char *)path ,SHARED_LOCK)) {
219 dirLock2=DupLock(dirLock);
220 dirLock2= CurrentDir(dirLock2);
221 fibp=AllocMem(sizeof(struct FileInfoBlock),0);
223 if(Examine(dirLock,fibp)){
224 while(ExNext(dirLock,fibp)){
225 if(!strncmp(fibp->fib_FileName,files,chklen)){
226 DeleteFile(fibp->fib_FileName);
230 FreeMem(fibp,sizeof(struct FileInfoBlock));
233 UnLock(CurrentDir(dirLock2));
238 /* This size makes that most files can be copied with two Read()/Write()s */
241 #define COPYSIZE 4096
243 char *CopyFile(from, to)
244 const char *from, *to;
246 register BPTR fromFile, toFile;
247 register char *buffer;
251 buffer = (char *) alloc(COPYSIZE);
252 if (fromFile = Open( (char *)from, MODE_OLDFILE)) {
253 if (toFile = Open( (char *)to, MODE_NEWFILE)) {
254 while (size = Read(fromFile, buffer, (long)COPYSIZE)) {
256 error = "Read error";
259 if (size != Write(toFile, buffer, size)) {
260 error = "Write error";
266 error = "Cannot open destination";
269 error = "Cannot open source (this should not occur)";
275 /* this should be replaced */
276 saveDiskPrompt(start)
278 char buf[BUFSIZ], *bp;
280 if (sysflags.asksavedisk) {
281 /* Don't prompt if you can find the save file */
282 if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
284 #if defined(TTY_GRAPHICS)
285 if (windowprocs.win_init_nhwindows
286 != amii_procs.win_init_nhwindows)
287 clear_nhwindow(WIN_MAP);
289 #if defined(AMII_GRAPHICS)
290 if (windowprocs.win_init_nhwindows
291 == amii_procs.win_init_nhwindows)
292 clear_nhwindow(WIN_BASE);
296 pline("If save file is on a SAVE disk, put that disk in now.");
297 if (strlen(SAVEF) > QBUFSZ - 25 - 22)
298 panic("not enough buffer space for prompt");
300 #if defined(TTY_GRAPHICS)
301 if (windowprocs.win_init_nhwindows != amii_procs.win_init_nhwindows) {
302 getlin("File name ?", buf);
303 clear_nhwindow(WIN_MAP);
306 #if defined(AMII_GRAPHICS)
307 if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows) {
308 getlind("File name ?", buf, SAVEF);
309 clear_nhwindow(WIN_BASE);
312 clear_nhwindow(WIN_MESSAGE);
313 if (!start && *buf == '\033')
316 /* Strip any whitespace. Also, if nothing was entered except
317 * whitespace, do not change the value of SAVEF.
319 for (bp = buf; *bp; bp++) {
321 strncpy(SAVEF, bp, PATHLEN);
329 /* Return 1 if the record file was found */
335 if (file = fopenp(RECORD, "r")) {
344 * Under MSDOS: Prompt for game disk, then check for record file.
345 * For Amiga: do nothing, but called from restore.c
354 * Add a slash to any name not ending in / or :. There must
367 if (*ptr != '/' && *ptr != ':') {
379 raw_printf("Hit <RETURN> %s.", str);
380 while ((ch = nhgetch()) != '\n' && ch != '\r')
384 /* Follow the PATH, trying to fopen the file.
390 register const char *name, *mode;
392 register char *bp, *pp, lastch;
394 register BPTR theLock;
397 /* Try the default directory first. Then look along PATH.
399 if (strlen(name) >= BUFSIZ)
402 if (theLock = Lock(buf, SHARED_LOCK)) {
404 if (fp = fopen(buf, mode))
410 while (*pp && *pp != PATHSEP) {
411 if (bp > buf + BUFSIZ - 1)
413 lastch = *bp++ = *pp++;
415 if (lastch != ':' && lastch != '/' && bp != buf)
417 if (bp + strlen(name) > buf + BUFSIZ - 1)
420 if (theLock = Lock(buf, SHARED_LOCK)) {
422 if (fp = fopen(buf, mode))
435 * A not general-purpose directory changing routine.
436 * Assumes you want to return to the original directory eventually,
437 * by chdir()ing to orgdir (which is defined in pcmain.c).
438 * Assumes -1 is not a valid lock, since 0 is valid.
441 #define NO_LOCK ((BPTR) -1)
443 static BPTR OrgDirLock = NO_LOCK;
445 chdir(dir) char *dir;
447 extern char orgdir[];
450 /* We want to go back to where we came from. */
451 if (OrgDirLock != NO_LOCK) {
452 UnLock(CurrentDir(OrgDirLock));
453 OrgDirLock = NO_LOCK;
457 * Go to some new place. If still at the original
458 * directory, save the FileLock.
462 if (newDir = Lock((char *) dir, SHARED_LOCK)) {
463 if (OrgDirLock == NO_LOCK) {
464 OrgDirLock = CurrentDir(newDir);
466 UnLock(CurrentDir(newDir));
469 return -1; /* Failed */
472 /* CurrentDir always succeeds if you have a lock */
478 /* Chdir back to original directory
485 extern char orgdir[];
489 chdir(orgdir); /* chdir, not chdirx */
493 if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows)
499 void regularize(s) /* normalize file name - we don't like :'s or /'s */
504 while ((lp = index(s, ':')) || (lp = index(s, '/')))