1 /* SCCS Id: @(#)amidos.c 3.2 2000/01/12
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);
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)
89 getlin("Enter CLI Command...", buf );
91 i = System( buf, NULL );
96 pline("No mysterious force prevented you from using multitasking.");
105 # define Sprintf (void) sprintf
110 * This routine uses an approximation of the free bytes on a disk.
111 * How large a file you can actually write depends on the number of
112 * extension blocks you need for it.
113 * In each extenstion block there are maximum 72 pointers to blocks,
114 * so every 73 disk blocks have only 72 available for data.
115 * The (necessary) file header is also good for 72 data block pointers.
117 /* TODO: update this for FFS */
122 register long freeBytes = 0;
123 register struct InfoData *infoData; /* Remember... longword aligned */
127 * Find a valid path on the device of which we want the free space.
128 * If there is a colon in the name, it is an absolute path
129 * and all up to the colon is everything we need.
130 * Remember slashes in a volume name are allowed!
131 * If there is no colon, it is relative to the current directory,
132 * so must be on the current device, so "" is enough...
135 register char *colon;
137 strncpy(fileName, path, sizeof(fileName) - 1);
139 if (colon = index(fileName, ':'))
146 infoData = (struct InfoData *) alloc(sizeof(struct InfoData));
147 if (fileLock = Lock(fileName, SHARED_LOCK)) {
148 if (Info(fileLock, infoData)) {
149 /* We got a kind of DOS volume, since we can Lock it. */
150 /* Calculate number of blocks available for new file */
151 /* Kludge for the ever-full VOID: (oops RAM:) device */
152 if (infoData->id_UnitNumber == -1 &&
153 infoData->id_NumBlocks == infoData->id_NumBlocksUsed) {
154 freeBytes = AvailMem(0L) - 64 * 1024L;
155 /* Just a stupid guess at the */
156 /* Ram-Handler overhead per block: */
157 freeBytes -= freeBytes/16;
159 /* Normal kind of DOS file system device/volume */
160 freeBytes = infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
161 freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
162 freeBytes *= infoData->id_BytesPerBlock;
179 register BPTR fileLock;
180 register struct FileInfoBlock *fileInfoBlock;
181 register long size = 0;
183 fileInfoBlock = (struct FileInfoBlock *)alloc(sizeof(struct FileInfoBlock));
184 if (fileLock = Lock(file, SHARED_LOCK)) {
185 if (Examine(fileLock, fileInfoBlock)) {
186 size = fileInfoBlock->fib_Size;
196 eraseall(path, files)
197 const char *path, *files;
199 BPTR dirLock, dirLock2;
200 struct FileInfoBlock *fibp;
203 if(files != alllevels)panic("eraseall");
205 chklen=(int)index(files,'*')-(int)files;
207 if (dirLock = Lock( (char *)path ,SHARED_LOCK)) {
208 dirLock2=DupLock(dirLock);
209 dirLock2= CurrentDir(dirLock2);
210 fibp=AllocMem(sizeof(struct FileInfoBlock),0);
212 if(Examine(dirLock,fibp)){
213 while(ExNext(dirLock,fibp)){
214 if(!strncmp(fibp->fib_FileName,files,chklen)){
215 DeleteFile(fibp->fib_FileName);
219 FreeMem(fibp,sizeof(struct FileInfoBlock));
222 UnLock(CurrentDir(dirLock2));
227 /* This size makes that most files can be copied with two Read()/Write()s */
230 #define COPYSIZE 4096
232 char *CopyFile(from, to)
233 const char *from, *to;
235 register BPTR fromFile, toFile;
236 register char *buffer;
240 buffer = (char *) alloc(COPYSIZE);
241 if (fromFile = Open( (char *)from, MODE_OLDFILE)) {
242 if (toFile = Open( (char *)to, MODE_NEWFILE)) {
243 while (size = Read(fromFile, buffer, (long)COPYSIZE)) {
245 error = "Read error";
248 if (size != Write(toFile, buffer, size)) {
249 error = "Write error";
255 error = "Cannot open destination";
258 error = "Cannot open source (this should not occur)";
264 /* this should be replaced */
265 saveDiskPrompt(start)
267 char buf[BUFSIZ], *bp;
270 if (flags.asksavedisk) {
271 /* Don't prompt if you can find the save file */
272 if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
274 #if defined(TTY_GRAPHICS)
275 if(windowprocs.win_init_nhwindows!=amii_procs.win_init_nhwindows)
276 clear_nhwindow( WIN_MAP );
278 #if defined(AMII_GRAPHICS)
279 if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
280 clear_nhwindow( WIN_BASE );
284 pline( "If save file is on a SAVE disk, put that disk in now." );
285 if( strlen( SAVEF ) > QBUFSZ - 25 - 22 )
286 panic( "not enough buffer space for prompt" );
288 #if defined(TTY_GRAPHICS)
289 if(windowprocs.win_init_nhwindows!=amii_procs.win_init_nhwindows){
290 getlin("File name ?",buf);
291 clear_nhwindow( WIN_MAP );
294 #if defined(AMII_GRAPHICS)
295 if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows){
296 getlind("File name ?", buf, SAVEF);
297 clear_nhwindow( WIN_BASE );
300 clear_nhwindow( WIN_MESSAGE);
301 if (!start && *buf == '\033')
304 /* Strip any whitespace. Also, if nothing was entered except
305 * whitespace, do not change the value of SAVEF.
307 for (bp = buf; *bp; bp++) {
309 strncpy(SAVEF, bp, PATHLEN);
317 /* Return 1 if the record file was found */
323 if (file = fopenp(RECORD, "r")) {
332 * Under MSDOS: Prompt for game disk, then check for record file.
333 * For Amiga: do nothing, but called from restore.c
340 * Add a slash to any name not ending in / or :. There must
352 if (*ptr != '/' && *ptr != ':') {
365 raw_printf("Hit <RETURN> %s.", str);
366 while ((ch = nhgetch()) != '\n' && ch != '\r' )
370 /* Follow the PATH, trying to fopen the file.
376 register const char *name, *mode;
378 register char *bp, *pp, lastch;
380 register BPTR theLock;
383 /* Try the default directory first. Then look along PATH.
385 if (strlen(name) >= BUFSIZ) return( NULL );
387 if (theLock = Lock(buf, SHARED_LOCK)) {
389 if (fp = fopen(buf, mode))
395 while (*pp && *pp != PATHSEP){
396 if( bp > buf + BUFSIZ - 1 ) return( NULL );
397 lastch = *bp++ = *pp++;
399 if (lastch != ':' && lastch != '/' && bp != buf)
401 if (bp + strlen(name) > buf + BUFSIZ - 1) return( NULL );
403 if (theLock = Lock(buf, SHARED_LOCK)) {
405 if (fp = fopen(buf, mode)) return fp;
417 * A not general-purpose directory changing routine.
418 * Assumes you want to return to the original directory eventually,
419 * by chdir()ing to orgdir (which is defined in pcmain.c).
420 * Assumes -1 is not a valid lock, since 0 is valid.
423 #define NO_LOCK ((BPTR) -1)
425 static BPTR OrgDirLock = NO_LOCK;
430 extern char orgdir[];
433 /* We want to go back to where we came from. */
434 if (OrgDirLock != NO_LOCK) {
435 UnLock(CurrentDir(OrgDirLock));
436 OrgDirLock = NO_LOCK;
440 * Go to some new place. If still at the original
441 * directory, save the FileLock.
445 if (newDir = Lock( (char *)dir, SHARED_LOCK)) {
446 if (OrgDirLock == NO_LOCK) {
447 OrgDirLock = CurrentDir(newDir);
449 UnLock(CurrentDir(newDir));
452 return -1; /* Failed */
455 /* CurrentDir always succeeds if you have a lock */
461 /* Chdir back to original directory
468 extern char orgdir[];
472 chdir(orgdir); /* chdir, not chdirx */
476 if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
483 regularize(s) /* normalize file name - we don't like :'s or /'s */
488 while((lp = index(s, ':')) || (lp = index(s, '/')))