|
|
1.1 root 1: /* amisysio.c */
2:
3: /*-
4: * Mike Rieser Dale Rahn
5: * 2410 Happy Hollow Rd. Apt D-10 540 Vine St.
6: * West Lafayette, IN 47906 West Lafayette, IN 47906
7: * [email protected] [email protected]
8: */
9:
10: #if AZTEC_C
11:
12: /*
13: * This file is only to supply behavior a little closer to UNIX for the Aztec
14: * Library functions stat() and creat().
15: *
16: * If you don't have a decent stat() function move the above #if to the
17: * end of the stat() function.
18: *
19: * The creat() function is pretty Aztec specific.
20: */
21:
22: #include "amistat.h"
23: #include <fcntl.h>
24: #include <string.h>
25: #include <dos/dos.h>
26: #include <dos/dosextens.h>
27: #include <clib/exec_protos.h>
28: #include <clib/dos_protos.h>
29:
30: #if AZTEC_C
31: #include <pragmas/exec_lib.h>
32: #include <pragmas/dos_lib.h>
33: #else
34: #include <pragmas/exec.h>
35: #include <pragmas/dos.h>
36: #endif
37:
38: /*-
39: * struct InfoData {
40: * LONG id_NumSoftErrors; // number of soft errors on disk
41: * LONG id_UnitNumber; // Which unit disk is (was) mounted on
42: * LONG id_DiskState; // See defines below
43: * LONG id_NumBlocks; // Number of blocks on disk
44: * LONG id_NumBlocksUsed; // Number of block in use
45: * LONG id_BytesPerBlock;
46: * LONG id_DiskType; // Disk Type code
47: * BPTR id_VolumeNode; // BCPL pointer to volume node
48: * LONG id_InUse; // Flag, zero if not in use
49: * }; // InfoData
50: * returned by Info(), must be on a 4 byte boundary
51: */
52: /*-
53: * struct FileInfoBlock {
54: * LONG fib_DiskKey;
55: * LONG fib_DirEntryType; // Type of Directory. If < 0, then a plain file.
56: * // If > 0 a directory
57: * char fib_FileName[108]; // Null terminated. Max 30 chars used for now
58: * LONG fib_Protection; // bit mask of protection, rwxd are 3-0.
59: * LONG fib_EntryType;
60: * LONG fib_Size; // Number of bytes in file
61: * LONG fib_NumBlocks; // Number of blocks in file
62: * struct DateStamp fib_Date;// Date file last changed
63: * char fib_Comment[80]; // Null terminated comment associated with file
64: * char fib_Reserved[36];
65: * }; // FileInfoBlock
66: * filled by Examin(), must be on a 4 byte boundary
67: */
68:
69: int
70: stat(char *path, struct stat *statbuf)
71: {
72: struct FileLock *lock;
73: struct FileInfoBlock *pFIB;
74: struct InfoData *pID;
75: int success = 0;
76:
77: /* Zero the stat buffer. */
78: memset(statbuf, '\000', sizeof(struct stat));
79:
80: /* Get Lock */
81: lock = (struct FileLock *) Lock((UBYTE *) path, ACCESS_READ);
82: if ((struct FileLock *) 0 == lock)
83: { /* Lock() fails if file is a softlink */
84: if (ERROR_IS_SOFT_LINK == IoErr())
85: {
86: statbuf->st_mode |= S_IFLNK;/* symbolic link */
87: return 0;
88: } else
89: return -1;
90: }
91: /* Allocate InfoData */
92: pID = (struct InfoData *) AllocMem(sizeof(struct InfoData), 0);
93:
94: if ((struct InfoData *) 0 == pID)
95: {
96: UnLock((BPTR) lock);
97: return -1;
98: }
99: /* Allocate FileInfoBlock */
100: pFIB = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), 0);
101:
102: if ((struct FileInfoBlock *) 0 == pFIB)
103: {
104: FreeMem(pID, sizeof(struct InfoData));
105:
106: UnLock((BPTR) lock);
107: return -1;
108: }
109: /* Fill InfoData */
110: if (DOSFALSE == Info((BPTR) lock, pID))
111: { /* Not critical */
112: FreeMem(pID, sizeof(struct InfoData));
113:
114: pID = (struct InfoData *) 0;
115: }
116: /* Fill FileInfoBlock */
117: if (DOSFALSE == Examine((BPTR) lock, pFIB))
118: {
119: FreeMem(pID, sizeof(struct InfoData));
120: FreeMem(pFIB, sizeof(struct FileInfoBlock));
121:
122: UnLock((BPTR) lock);
123: return -1;
124: }
125: statbuf->st_ino = pFIB->fib_DiskKey;/* inode's number */
126: ++statbuf->st_nlink;
127:
128: if (pFIB->fib_DirEntryType < 0)
129: { /* plain file */
130: statbuf->st_mode |= S_IFREG;
131: } else
132: { /* >= 0 then directory */
133: statbuf->st_mode |= S_IFDIR;
134: }
135: if (pFIB->fib_DirEntryType == ST_SOFTLINK)
136: {
137: statbuf->st_mode |= S_IFLNK;
138: }
139: if (pFIB->fib_DirEntryType == ST_SOFTLINK
140: || pFIB->fib_DirEntryType == ST_LINKDIR
141: || pFIB->fib_DirEntryType == ST_LINKFILE)
142: {
143: ++statbuf->st_nlink;
144: }
145: statbuf->st_flags = statbuf->st_attr = pFIB->fib_Protection;
146:
147: /* mask off arwed -> rwx and shift to owner bits */
148: statbuf->st_mode |= ((~0 ^ pFIB->fib_Protection) & 016) << 5;
149:
150: statbuf->st_size = pFIB->fib_Size;
151: if (pID)
152: statbuf->st_blksize = pID->id_BytesPerBlock; /* optimal blocksize for
153: * I/O */
154: statbuf->st_blocks = pFIB->fib_NumBlocks; /* actual number of blocks
155: * allocated */
156: statbuf->st_atime =
157: statbuf->st_mtime =
158: statbuf->st_ctime = pFIB->fib_Date.ds_Days * 24 * 60 * 60 +
159: pFIB->fib_Date.ds_Minute * 60 +
160: pFIB->fib_Date.ds_Tick / TICKS_PER_SECOND;
161:
162: UnLock((BPTR) lock);
163: if (pID)
164: FreeMem(pID, sizeof(struct InfoData));
165: FreeMem(pFIB, sizeof(struct FileInfoBlock));
166:
167: return 0;
168: }
169:
170:
171: /*
172: * Aztec creat() replacement.
173: *
174: * This one doesn't delete the file, thereby preserving the original file
175: * protection bits!
176: */
177: int
178: creat(const char *name, int mode)
179: {
180: int c = 0;
181: BPTR fh;
182:
183: if (isOldDOS())
184: return (_creat(name, mode));
185:
186: fh = Open((UBYTE *) name, MODE_READWRITE);
187: if ((BPTR) 0 == fh)
188: return (_open(name, O_WRONLY | O_TRUNC | O_CREAT, mode));
189: SetFileSize(fh, 0, OFFSET_BEGINNING); /* Set back to beginning */
190: Close(fh); /* Truncate at the start */
191:
192: return (_open(name, O_WRONLY, mode)); /* actually get a fd */
193: }
194:
195: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.