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
, '/')))