|
|
1.1 root 1: /*
2: * dos0.c
3: * cc -o dos dos[01234].c
4: * Read, write or format an MS-DOS filesystem (default: INFILE in dos1.h).
5: * For usage, see USAGE in dos0.h.
6: * Understands DOS 2.0 tree structured disks.
7: * Understands 1.5 and 2-byte FAT entries;
8: * does not understand 4-byte FAT entries.
9: * Prints some debugging information if compiled -DDEBUG.
10: */
11:
12: #include "dos0.h"
13:
14: /* Globals. */
15: short oldstyle; /* Indicates the this was a dos */
16: short aflag; /* ASCII text file */
17: short bflag; /* Binary text file */
18: unsigned char cohfile[NAMEMAX]; /* COHERENT filename */
19: unsigned char cmd[6 + NAMEMAX]; /* system() command buffer */
20: char * device = INFILE; /* Input device filename */
21: short estat; /* Exit status */
22: short (*fun)(); /* Function to execute */
23: short kflag; /* Use mtime, not current time */
24: short nflag; /* Sort by time, newest first */
25: short fflag; /* Force removal of rdonly files*/
26: long partseek; /* Extended MS-DOS part. seek */
27: short pflag; /* Extract/replace is piped */
28: DIR * root; /* Root directory */
29: short sflag; /* Suppress subdirectory x/r */
30: MDIR * volume; /* Volume label */
31:
32: short xpart; /* Extended MS-DOS partition */
33: char * base, basehold[35]; /* Base for path-including copies */
34: char * base1;
35:
36: char ext[512]; /* Ascii Extension list */
37: short sext = 0; /* size of extension list */
38: short numargs;
39: short isdir_keep;
40:
41: char *tran_dev();
42: char *tran_file();
43: short die_signal();
44:
45: main(argc, argv) short argc; char *argv[];
46: {
47: register short mode;
48: short tv, c, i = 0, dev = 2, j, k = 0, dargs = 0;
49: char *tmp;
50:
51: argv0 = argv[0];
52:
53: if (strcmp((argv[0] + strlen(argv[0]) - 3), "dos")) {
54: usagemsg = USAGE;
55: if (argc < 2)
56: usage(NULL);
57:
58: mode = 2;
59: tmp = argv[0];
60: if ((*argv[1] == '-') && (argv[1][1] != '\0')) {
61: while ((c = *argv[1]++) != '\0') {
62: dargs = 1;
63: switch (c) {
64: case 'a':
65: case 'm': aflag++; break;
66: case 'b':
67: case 'r': bflag++; break;
68: case 'k': kflag++; break;
69: case 'f': fflag++; break;
70: case 's': sflag++; break;
71: case 'n': nflag++; break;
72: case 'v': vflag++; break;
73: case '1':
74: case '2':
75: case '3':
76: case '4':
77: case '5':
78: case '6':
79: case '7':
80: case '8':
81: case '9': xpart = c - '0';
82: break;
83: case '-': break;
84: default:
85: fatal1("Invalid argument %c", c);
86: break;
87: }
88: }
89: }
90: else
91: dev--;
92:
93: if ((strstr(tmp, "cp")) || (strstr(tmp, "copy"))) {
94: if (!strstr(tmp, "dir"))
95: sflag++;
96: if (dev+2 > argc)
97: fatal1("Copy must include both a source and a"
98: " destination\n");
99: c=0;
100: for (j=dev; j < argc; j++)
101: if (strchr(argv[j], ':')) {
102: k++;
103: c=j;
104: }
105: if (k>1)
106: fatal1("Copy can only specify one DOS devic"
107: "e at a time.\n");
108: else if (!k)
109: fatal1("Use cp for COHERENT-COHERENT copies.\n");
110: if (c == dev) {
111: mode = 0;
112: fun = extract;
113: device = tran_dev(argv[dev]);
114: if((argv[dev] = tran_file(argv[dev])) != NULL)
115: tv=1;
116: else
117: tv=0;
118: tmp = &argv[dev];
119: base1 = argv[dev+1];
120: }
121: else {
122: fun = replace;
123: device = tran_dev(argv[argc-1]);
124: base1 = tran_file(argv[argc-1]);
125: argv[argc-1] = NULL;
126: tv = argc - (1 + dev);
127: tmp = &argv[dev];
128: }
129: }
130: else if (strstr(tmp, "format")) {
131: tv=argc - (2 + dargs);
132: tmp = &argv[dev+1];
133: device = tran_dev(argv[dev]);
134: fun = format;
135: }
136: else if (strstr(tmp, "mkdir")) {
137: if (argc > 2 + dargs)
138: fatal("Too many arguments for MKDIR\n");
139:
140: device = tran_dev(argv[dev]);
141: if ((argv[dev] = tran_file(argv[dev])) != NULL)
142: tv=1;
143: else
144: fatal("Must specify a directory to create.\n");
145: tmp = &argv[dev];
146: fun = createdir;
147: }
148: else if (strstr(tmp, "cat")) {
149: if (argc > 2 + dargs)
150: fatal1("Too many arguments for doscat\n");
151:
152: device = tran_dev(argv[dev]);
153: if ((argv[dev] = tran_file(argv[dev])) != NULL)
154: tv=1;
155: else
156: fatal1("Must specify a file to display.\n");
157: tmp = &argv[dev];
158: fun = extract;
159: pflag++;
160: mode = 0;
161: }
162: else if ((strstr(tmp, "rm")) || (strstr(tmp, "del"))) {
163: device = tran_dev(argv[dev]);
164: if ((argv[dev] = tran_file(argv[dev])) != NULL)
165: tv=1;
166: else
167: tv=0;
168: tmp = &argv[dev];
169: fun = delete;
170: }
171: else if ((strstr(tmp, "dir")) || (strstr(tmp, "ls"))) {
172: device = tran_dev(argv[dev]);
173: if ((argv[dev] = tran_file(argv[dev])) != NULL)
174: tv=1;
175: else
176: tv=0;
177: tmp = &argv[dev];
178: fun = table;
179: mode = 0;
180: }
181: else if (strstr(tmp, "label")) {
182: tv=argc - (2 + dargs);
183: tmp = &argv[dev+1];
184: device = tran_dev(argv[dev]);
185: fun = label;
186: }
187: else
188: usage("Invalid command.\n\n");
189: }
190: else {
191: oldstyle = 1;
192: usagemsg = OUSAGE;
193: if (argc < 2)
194: usage(NULL);
195: if (argc == 2)
196: ++argc;
197: else
198: device = argv[2];
199: mode = key(argv[1]);
200: tv = argc - 3;
201: tmp = &argv[3];
202: strcpy(adev, device);
203: }
204:
205: make_lock();
206: if ((fsfd = open(device, mode)) < 0)
207: fatal("cannot open device %s", device);
208:
209: if (fun != format) {
210: /* Read the FAT and the root directory. */
211: readfat();
212: root = newdir(NULL, NULL, bpb->b_files);
213: readmdir(root);
214: }
215: numargs = tv;
216: (*fun)(tv , tmp);
217: if (fun != format) {
218: writedir(root);
219: if (fatcflag)
220: writefat();
221: free(fatcache);
222: }
223: rm_lock();
224: exit(estat);
225: }
226:
227:
228: #define DEFFILE "/etc/default/msdos"
229: char adev[80], dev[80];
230: char file[80];
231:
232: char *tran_dev(arg) char *arg;
233: {
234: FILE *fp;
235: char *b, c[80];
236: short found = 0;
237:
238: strcpy(dev, arg);
239: if ((b = strchr(dev, ':')) == NULL)
240: fatal1("Error: No device specified\n");
241:
242: *b = '\0';
243:
244: strcpy(adev, dev);
245: if (adev[0] != '/')
246: adev[0] = toupper(adev[0]);
247:
248: if ((fp = fopen(DEFFILE, "r")) != NULL) {
249: while (!feof(fp)) {
250: if(fgets(c, 79, fp)) {
251: if ((c[0] != '#') && (c[0] != '\n')) {
252: if (c[0] == '.') {
253: short i = 0;
254: while (c[i] != '\n')
255: ext[sext++] = c[i++];
256: }
257: else if (!found){
258: if (b = strchr(c, '=')) {
259: *b++ = '\0';
260: if (!strcmp(c, dev)) {
261: *strpbrk(b,"\t\n #")='\0';
262: strcpy(dev, b);
263: if(b=strchr(dev,';')){
264: *b='\0';
265: xpart=atoi(b+1);
266: }
267: found++;
268: }
269: }
270: }
271: }
272: }
273: }
274: }
275: fclose(fp);
276: ext[sext++] = '.';
277: ext[sext++] = '\0';
278: return dev;
279: }
280:
281:
282: char *tran_file(arg) char *arg;
283: {
284: char *t;
285:
286: t = strchr(arg, ':') + 1;
287: if (*t == '/')
288: t++;
289: if (*t) {
290: if (strcpy(file, t));
291: return file;
292: }
293: else
294: return NULL;
295: }
296:
297:
298: #define SPOOLDIR "/tmp"
299: #define LOCKPRE "LCK.."
300: char lockfn[64];
301:
302: make_lock()
303: {
304: short lockfd, i;
305: char pidstring[6];
306: char *tmp = strrchr(device, '/') + 1;
307:
308: #ifdef _I386
309: for (i=1; i < 13; i++)
310: #else
311: for (i=1; i < 12; i++)
312: #endif
313: signal(i, die_signal);
314:
315: sprintf(lockfn, "%s/%s%s", SPOOLDIR, LOCKPRE, tmp ? tmp : device);
316: if ((lockfd = open(lockfn, O_RDONLY)) != -1)
317: {
318: if ((read(lockfd, &i, sizeof(int)) != sizeof(int))
319: || (kill(i, 0) == -1))
320: {
321: close(lockfd);
322: }
323: else
324: fatal1("Device %s is in use.\n", device);
325: }
326: if((lockfd=creat(lockfn, 0644)) == -1)
327: fatal1("Cannot lock Device %s.\n", device);
328:
329: sprintf(pidstring, "%d", getpid());
330: write(lockfd, pidstring, strlen(pidstring));
331: close(lockfd);
332: }
333:
334: short die_signal(s) short s;
335: {
336: fflush(stdout);
337: fatal("received signal %d, quitting.\n", s);
338: }
339:
340: rm_lock()
341: {
342: short lockfd; /* pointer to file to read */
343: int chars_read;
344: char gotpid[7]; /* String of the PID that was in the lockfile */
345:
346: /* open the lock file for read, abort on failure */
347: if(-1 == (lockfd = (open(lockfn, 0))))
348: fatal1("Error opening %s\n", argv0, lockfn);
349:
350: /* read the contents of the file. Abort if empty */
351: if ( -1 == (chars_read = read(lockfd, gotpid, 6))) {
352: close(lockfd);
353: fatal1("Error reading %s\n", lockfn);
354: }
355:
356: gotpid[chars_read] = '\0'; /* NUL terminate the string. */
357: if (atoi(gotpid) != getpid()){
358: close(lockfd);
359: fatal1("%s is not our lock file\n", lockfn);
360: }else{
361: if ( unlink(lockfn) < 0 ) {
362: close(lockfd);
363: fatal1("Can't unlink: %s\n", lockfn);
364: }
365: close(lockfd);
366: return( 0 );
367: }
368: }
369:
370: /* end of dos0.c */
371:
372:
373:
374:
375:
376:
377:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.