more DUMPLOG lint
[aNetHack.git] / sys / amiga / amidos.c
blob2ae3bee19775531206ef87897e8eb505fb927da1
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. */
6 /*
7 * An assortment of imitations of cheap plastic MSDOS and Unix functions.
8 */
10 #include "hack.h"
11 #include "winami.h"
13 /* Defined in config.h, let's undefine it here (static function below) */
14 #undef strcmpi
16 #include <libraries/dos.h>
17 #include <exec/execbase.h>
18 #include <intuition/intuition.h>
20 #undef COUNT
21 #if defined(__SASC_60) || defined(__GNUC__)
22 #include <proto/exec.h>
23 #include <proto/dos.h>
24 #endif
26 #ifdef AZTEC_50
27 #include <functions.h>
28 #undef strcmpi
29 #endif
31 /* Prototypes */
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;
39 #ifndef __SASC_60
40 int Enable_Abort = 0; /* for stdio package */
41 #endif
43 /* Initial path, so we can find NetHack.cnf */
44 char PATH[PATHLEN] = "NetHack:";
46 static boolean record_exists(void);
48 void
49 flushout()
51 (void) fflush(stdout);
54 #ifndef getuid
55 getuid()
57 return 1;
59 #endif
61 #ifndef getlogin
62 char *
63 getlogin()
65 return ((char *) NULL);
67 #endif
69 #ifndef AZTEC_50
70 int
71 abs(x)
72 int x;
74 return x < 0 ? -x : x;
76 #endif
78 #ifdef SHELL
79 int
80 dosh()
82 int i;
83 char buf[BUFSZ];
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);
89 if (buf[0] != '\033')
90 i = System(buf, NULL);
91 } else {
92 i = 0;
93 pline("No mysterious force prevented you from using multitasking.");
95 return i;
97 #endif /* SHELL */
99 #ifdef MFLOPPY
100 #include <ctype.h>
102 #define Sprintf (void) sprintf
104 #define EXTENSION 72
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 */
115 long
116 freediskspace(path)
117 char *path;
119 #ifdef UNTESTED
120 /* these changes from Patric Mueller <bhaak@gmx.net> for AROS to
121 * handle larger disks. Also needs limits.h and aros/oldprograms.h
122 * for AROS. (keni)
124 unsigned long long freeBytes = 0;
125 #else
126 register long freeBytes = 0;
127 #endif
128 register struct InfoData *infoData; /* Remember... longword aligned */
129 char fileName[32];
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);
143 fileName[31] = 0;
144 if (colon = index(fileName, ':'))
145 colon[1] = '\0';
146 else
147 fileName[0] = '\0';
150 BPTR fileLock;
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;
163 } else {
164 /* Normal kind of DOS file system device/volume */
165 freeBytes =
166 infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
167 freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
168 freeBytes *= infoData->id_BytesPerBlock;
169 #ifdef UNTESTED
170 if (freeBytes > LONG_MAX) {
171 freeBytes = LONG_MAX;
173 #endif
175 if (freeBytes < 0)
176 freeBytes = 0;
178 UnLock(fileLock);
180 free(infoData);
181 return freeBytes;
185 long
186 filesize(file)
187 char *file;
189 register BPTR fileLock;
190 register struct FileInfoBlock *fileInfoBlock;
191 register long size = 0;
193 fileInfoBlock =
194 (struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock));
195 if (fileLock = Lock(file, SHARED_LOCK)) {
196 if (Examine(fileLock, fileInfoBlock)) {
197 size = fileInfoBlock->fib_Size;
199 UnLock(fileLock);
201 free(fileInfoBlock);
202 return size;
205 #if 0
206 void
207 eraseall(path, files)
208 const char *path, *files;
210 BPTR dirLock, dirLock2;
211 struct FileInfoBlock *fibp;
212 int chklen;
213 #ifdef BETA
214 if(files != alllevels)panic("eraseall");
215 #endif
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);
222 if(fibp){
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));
232 UnLock(dirLock);
233 UnLock(CurrentDir(dirLock2));
236 #endif
238 /* This size makes that most files can be copied with two Read()/Write()s */
240 #if 0 /* Unused */
241 #define COPYSIZE 4096
243 char *CopyFile(from, to)
244 const char *from, *to;
246 register BPTR fromFile, toFile;
247 register char *buffer;
248 register long size;
249 char *error = NULL;
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)) {
255 if (size == -1){
256 error = "Read error";
257 break;
259 if (size != Write(toFile, buffer, size)) {
260 error = "Write error";
261 break;
264 Close(toFile);
265 } else
266 error = "Cannot open destination";
267 Close(fromFile);
268 } else
269 error = "Cannot open source (this should not occur)";
270 free(buffer);
271 return error;
273 #endif
275 /* this should be replaced */
276 saveDiskPrompt(start)
278 char buf[BUFSIZ], *bp;
279 BPTR fileLock;
280 if (sysflags.asksavedisk) {
281 /* Don't prompt if you can find the save file */
282 if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
283 UnLock(fileLock);
284 #if defined(TTY_GRAPHICS)
285 if (windowprocs.win_init_nhwindows
286 != amii_procs.win_init_nhwindows)
287 clear_nhwindow(WIN_MAP);
288 #endif
289 #if defined(AMII_GRAPHICS)
290 if (windowprocs.win_init_nhwindows
291 == amii_procs.win_init_nhwindows)
292 clear_nhwindow(WIN_BASE);
293 #endif
294 return 1;
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");
299 /* THIS IS A HACK */
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);
305 #endif
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);
311 #endif
312 clear_nhwindow(WIN_MESSAGE);
313 if (!start && *buf == '\033')
314 return 0;
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++) {
320 if (!isspace(*bp)) {
321 strncpy(SAVEF, bp, PATHLEN);
322 break;
326 return 1;
329 /* Return 1 if the record file was found */
330 static boolean
331 record_exists()
333 FILE *file;
335 if (file = fopenp(RECORD, "r")) {
336 fclose(file);
337 return TRUE;
339 return FALSE;
342 #ifdef MFLOPPY
344 * Under MSDOS: Prompt for game disk, then check for record file.
345 * For Amiga: do nothing, but called from restore.c
347 void
348 gameDiskPrompt()
351 #endif
354 * Add a slash to any name not ending in / or :. There must
355 * be room for the /.
357 void
358 append_slash(name)
359 char *name;
361 char *ptr;
363 if (!*name)
364 return;
366 ptr = eos(name) - 1;
367 if (*ptr != '/' && *ptr != ':') {
368 *++ptr = '/';
369 *++ptr = '\0';
373 void
374 getreturn(str)
375 const char *str;
377 int ch;
379 raw_printf("Hit <RETURN> %s.", str);
380 while ((ch = nhgetch()) != '\n' && ch != '\r')
381 continue;
384 /* Follow the PATH, trying to fopen the file.
386 #define PATHSEP ';'
388 FILE *
389 fopenp(name, mode)
390 register const char *name, *mode;
392 register char *bp, *pp, lastch;
393 register FILE *fp;
394 register BPTR theLock;
395 char buf[BUFSIZ];
397 /* Try the default directory first. Then look along PATH.
399 if (strlen(name) >= BUFSIZ)
400 return (NULL);
401 strcpy(buf, name);
402 if (theLock = Lock(buf, SHARED_LOCK)) {
403 UnLock(theLock);
404 if (fp = fopen(buf, mode))
405 return fp;
407 pp = PATH;
408 while (pp && *pp) {
409 bp = buf;
410 while (*pp && *pp != PATHSEP) {
411 if (bp > buf + BUFSIZ - 1)
412 return (NULL);
413 lastch = *bp++ = *pp++;
415 if (lastch != ':' && lastch != '/' && bp != buf)
416 *bp++ = '/';
417 if (bp + strlen(name) > buf + BUFSIZ - 1)
418 return (NULL);
419 strcpy(bp, name);
420 if (theLock = Lock(buf, SHARED_LOCK)) {
421 UnLock(theLock);
422 if (fp = fopen(buf, mode))
423 return fp;
425 if (*pp)
426 pp++;
428 return NULL;
430 #endif /* MFLOPPY */
432 #ifdef CHDIR
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[];
449 if (dir == 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;
455 } else {
457 * Go to some new place. If still at the original
458 * directory, save the FileLock.
460 BPTR newDir;
462 if (newDir = Lock((char *) dir, SHARED_LOCK)) {
463 if (OrgDirLock == NO_LOCK) {
464 OrgDirLock = CurrentDir(newDir);
465 } else {
466 UnLock(CurrentDir(newDir));
468 } else {
469 return -1; /* Failed */
472 /* CurrentDir always succeeds if you have a lock */
473 return 0;
476 #endif /* CHDIR */
478 /* Chdir back to original directory
480 #undef exit
481 void
482 nethack_exit(code)
484 #ifdef CHDIR
485 extern char orgdir[];
486 #endif
488 #ifdef CHDIR
489 chdir(orgdir); /* chdir, not chdirx */
490 #endif
492 #ifdef AMII_GRAPHICS
493 if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows)
494 CleanUp();
495 #endif
496 exit(code);
499 void regularize(s) /* normalize file name - we don't like :'s or /'s */
500 register char *s;
502 register char *lp;
504 while ((lp = index(s, ':')) || (lp = index(s, '/')))
505 *lp = '_';