|
|
1.1.1.2 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.2 root 3: *
1.1 root 4: * pos-disk.c: Creates pseudo dev: handler. Copy tracks to rawfile
5: * (used in zfile.c).
1.1.1.2 root 6: *
1.1 root 7: * Copyright 1997, Samuel Devulder.
8: */
9:
10: /****************************************************************************/
11:
12: #include "sysconfig.h"
13: #include "sysdeps.h"
14:
15: #include <ctype.h>
16: #include <signal.h>
17:
18: #include "options.h"
19: #include "memory.h"
20: #include "custom.h"
21: #include "keyboard.h"
22: #include "keybuf.h"
23: #include "disk.h"
24: #include "debug.h"
25: #include "gui.h"
26:
27: /****************************************************************************/
28:
29: struct pOS_Locale;
30: struct pOS_Library;
31: struct pOS_ExecBase;
32: struct pOS_DosBase;
33: struct pOS_Method;
34: struct pOS_Resource;
35: struct pOS_RawDoFmtData;
36: struct pOS_AsciiDoFmtData;
37: struct pOS_AsciiFmtData;
38: struct pOS_ClassGrp;
39: struct pOS_DosDevPathInfo;
40: struct pOS_ShellScript;
41: struct pOS_SegmentInfo;
42: struct IClass;
43: struct Isrvstr;
44: struct TagItem;
45: struct MemHeader;
46: struct SemaphoreMessage;
47: struct StackSwapStruct;
48: struct Interrupt;
49: struct StandardPacket;
50: struct InfoData;
51: struct WBStartup;
52:
53: #define _SIZE_T /* to avoid interference with <sys/types.h> */
54: #include <pExec/Types.h>
55: #include <pExec/MsgPort.h>
56: #include <pExec/Device.h>
57: #include <pDOS/Lock.h>
58: #include <pDOS/Files.h>
59: #include <pDOS/DosSig.h>
60: #include <pDOS/DosErrors.h>
61: #include <pDevice/Trackdisk.h>
62:
63: #include <pInline/pExec2.h>
64: #include <pInline/pDos2.h>
65:
66: extern struct pOS_ExecBase *gb_ExecBase;
67: extern struct pOS_ExecLibFunction *gb_ExecLib;
68: extern struct pOS_DosBase *gb_DosBase;
69:
70: /****************************************************************************/
71:
72: char *amiga_dev_path = "DEV:";
73: char *ixemul_dev_path = "/dev/";
74:
75: int readdevice(char *name, char *dst);
76: void initpseudodevices(void);
77: void closepseudodevices(void);
78: char *to_unix_path(char *s);
79: char *from_unix_path(char *s);
80: void split_dir_file(char *src, char **dir, char **file);
81:
82: /****************************************************************************/
83:
84: static char *pseudo_dev_path = "T:DEV";
85:
86: static char pseudo_dev_created = 0;
87: static char pseudo_dev_assigned = 0;
88: static char dfx_done[4];
89:
90: static int device_exists(char *device_name, int device_unit);
91:
92: /****************************************************************************/
1.1.1.2 root 93: /* support routines to handle unix filename convention
1.1 root 94: */
95: char *to_unix_path(char *s)
96: {
97: char *t,*r,*u;
98: int l;
99:
100: for(u=s,l=0;*u;++u,++l) if(*u=='/' || *u==':') l+=2;
101:
102: r = t = malloc(1+l);
103: if(!r) return NULL;
104:
105: for(u=s;*u && *u!=':';++u);
106: if(*u) {
1.1.1.2 root 107: *t++='/';
108: while(*s!=':') *t++=*s++;
109: *t++='/';++s;
1.1 root 110: }
111: while(*s=='/') {*t++='.';*t++='.';*t++=*s++;}
112: while(*s) {
1.1.1.2 root 113: if(s[0]=='/' && s[1]=='/') {*t++=*s++;*t++='.';*t++='.';*t++=*s++;}
114: else *t++=*s++;
1.1 root 115: }
116: *t='\0';
117: return r;
118: }
119:
120: /****************************************************************************/
121:
122: char *from_unix_path(char *s)
123: {
124: char *t,*r;
125:
126: r = t = malloc(strlen(s)+1);
127: if(!r) return NULL;
128:
129: if(*s=='/') {
1.1.1.2 root 130: ++s;
131: while(*s && *s!='/') *t++=*s++;
132: if(*s=='/') {*t++=':';++s;}
1.1 root 133: }
134:
135: while(*s) {
1.1.1.2 root 136: if(s[0]=='.' && s[1]=='.') s+=2;
137: else *t++=*s++;
1.1 root 138: }
139:
140: *t='\0';
141:
142: return r;
143: }
144:
145: /****************************************************************************/
146:
147: void split_dir_file(char *src, char **dir, char **file)
148: { /* note: src is freed() */
149: char *s=src;
150:
151: while(*s) ++s;
152: while(s>src && (*s!=':' && *s!='/')) --s;
153: if(*s==':' || *s=='/') {
1.1.1.2 root 154: *file = my_strdup(s+1);
155: s[1] = '\0';
156: *dir = my_strdup(src);
157: free(src);
1.1 root 158: } else {
1.1.1.2 root 159: *file = src;
160: *dir = my_strdup("");
1.1 root 161: }
162: }
163:
164: /****************************************************************************/
165: /*
166: * Creates peudo DEV:DFx files.
167: */
168: void initpseudodevices(void)
169: {
170: struct pOS_FileLock *lock;
171: int i;
172:
173: /* check for T: and TMP: */
174: lock = pOS_LockObject(NULL, "T:", FILELKACC_Shared|FILELKACC_NoReq);
175: if(!lock) {
176: pOS_CreateDosAssign("T",NULL,"RAM:",DDTYP_Assign);
177: } else pOS_UnlockObject(lock);
178:
179: lock = pOS_LockObject(NULL, "TMP:", FILELKACC_Shared|FILELKACC_NoReq);
180: if(!lock) {
181: pOS_CreateDosAssign("TMP",NULL,"RAM:",DDTYP_Assign);
182: } else pOS_UnlockObject(lock);
183:
184: pseudo_dev_created = 0;
185: pseudo_dev_assigned = 0;
186: for(i=0;i<4;++i) dfx_done[i]=0;
187:
188: /* check if dev: already exists */
1.1.1.2 root 189: lock = pOS_LockObject(NULL, amiga_dev_path,
1.1 root 190: FILELKACC_Shared|FILELKACC_NoReq);
191: if(!lock) {
1.1.1.2 root 192: char name[80];
193: lock = pOS_LockObject(NULL, pseudo_dev_path,
1.1 root 194: FILELKACC_Shared|FILELKACC_NoReq);
1.1.1.2 root 195: if(!lock) {
196: /* create it */
197: lock = pOS_CreateDirectory(NULL, pseudo_dev_path);
198: if(!lock) goto fail;
199: pOS_UnlockObject(lock);
200: lock = pOS_LockObject(NULL, pseudo_dev_path,
1.1 root 201: FILELKACC_Shared|FILELKACC_NoReq);
1.1.1.2 root 202: pseudo_dev_created = 1;
203: }
204: strcpy(name,amiga_dev_path);
205: if(*name && name[strlen(name)-1]==':') name[strlen(name)-1]='\0';
206: if(!pOS_CreateDosAssign(name,lock,NULL, DDTYP_Assign)) {
1.1 root 207: pOS_UnlockObject(lock);
208: goto fail;
209: }
1.1.1.2 root 210: /* the lock is the assign now */
211: pseudo_dev_assigned = 1;
1.1 root 212: } else pOS_UnlockObject(lock);
213:
214: /* Create the dev:DFi entry */
215: for(i=0;i<4;++i) if(device_exists("pTrackdisk.device",i)) {
1.1.1.2 root 216: struct pOS_FileHandle *fd;
217: char name[80];
1.1 root 218:
1.1.1.2 root 219: sprintf(name,"%sDF%d",amiga_dev_path,i);
220: fd = pOS_OpenFile(NULL,name,FILEHDMOD_Write);
221: if(fd) {pOS_CloseFile(fd);dfx_done[i]=1;}
1.1 root 222: }
223:
224: return;
225: fail:
226: fprintf(stderr,"Failed to create pseudo DEV: entry!\n");
227: }
228:
229: /****************************************************************************/
230: /*
231: * Cleanup pseudo DEV:DFx
232: */
233: void closepseudodevices(void)
234: {
235: int i;
236: for(i=0;i<4;++i) if(dfx_done[i]) {
1.1.1.2 root 237: char name[80];
238: sprintf(name,"%sDF%d",amiga_dev_path,i);
239: pOS_DeleteObjectName(NULL, name);
240: dfx_done[i] = 0;
1.1 root 241: }
242:
243: if(pseudo_dev_assigned) {
1.1.1.2 root 244: char name[80];
245: strcpy(name,amiga_dev_path);
246: if(*name && name[strlen(name)-1]==':') name[strlen(name)-1]='\0';
247: pOS_DeleteDosAssign(name,NULL,0);
248: pseudo_dev_assigned = 0;
1.1 root 249: }
250:
251: if(pseudo_dev_created) {
1.1.1.2 root 252: pOS_DeleteObjectName(NULL, pseudo_dev_path);
253: pseudo_dev_created = 0;
1.1 root 254: }
255: }
256:
257: /****************************************************************************/
258: /*
259: * checks if a device exists
260: */
261: static int device_exists(char *device_name, int device_unit)
262: {
263: struct pOS_MsgPort port;
264: struct pOS_TrackdiskIO *IO;
265: int ret = 0;
266:
267: if(pOS_ConstructMsgPort(&port)) {
268: IO=(void *)pOS_CreateIORequest(&port, sizeof(struct pOS_TrackdiskIO));
269: if(IO) {
1.1.1.2 root 270: if(!pOS_OpenDevice(device_name, device_unit,
1.1 root 271: (struct pOS_IORequest*)IO, 0, 0)) {
272: pOS_CloseDevice((struct pOS_IORequest*)IO);
273: ret = 1;
274: }
275: pOS_DeleteIORequest((struct pOS_IORequest*)IO);
276: }
277: pOS_DestructMsgPort(&port);
278: }
279: return ret;
280: }
281:
282: /****************************************************************************/
283: /*
284: * extract the device and unit form a filename.
285: */
286: static void extract_dev_unit(char *name, char **dev_name, int *dev_unit)
287: {
288: struct pOS_DosMountDevice *dev = NULL;
289: char *s;
290:
291: if((s = malloc(strlen(name)+2))) {
292: sprintf(s,"%s:",name);
293: dev = pOS_GetDosMountName(s);
294: free(s);
1.1.1.2 root 295: }
1.1 root 296: if(dev && dev->dmd_Type == DMDTYP_BOD) {
297: *dev_name = strdup(dev->dmd_U.dmd_BOD.dmbod_DevName);
298: *dev_unit = dev->dmd_U.dmd_BOD.dmbod_UnitNum;
1.1.1.2 root 299: } else if((s = strrchr(name,'/'))) {
300: /* pTrackdisk[.device]/0 */
301: *dev_unit = atoi(s+1);
302: *dev_name = malloc(1 + s-name);
303: if(*dev_name) {
304: strncpy(*dev_name, name, 1 + s-name);
305: (*dev_name)[s-name]='\0';
306: }
307: } else {
308: /* ?? STRANGEDISK0: ?? */
309: *dev_unit = 0;
310: *dev_name = strdup(name);
1.1 root 311: }
312: if(*dev_name) {
1.1.1.2 root 313: char *s;
314: if(!(s = strrchr(*dev_name,'.'))) {
315: /* .device is missing: add it */
316: s = malloc(8+strlen(*dev_name));
317: if(s) {
318: sprintf(s,"%s.device",*dev_name);
319: free(*dev_name);
320: *dev_name = s;
321: }
322: }
1.1 root 323: }
324: }
325:
326: /****************************************************************************/
327:
328: static int dev_inhibit(char *name, int on)
329: {
330: struct pOS_DosDevice *dev;
331: if((dev = pOS_GetDosDevice(NULL, name))) {
332: pOS_InhibitDosDevice(dev,on?TRUE:FALSE);
333: return 1;
334: }
335: return 0;
336: }
337:
338: /****************************************************************************/
339: /*
340: * copy a device to a FILE
341: */
342: static int raw_copy(char *dev_name, int dev_unit, FILE *dst)
343: {
344: struct pOS_MsgPort Port;
345: struct pOS_TrackdiskIO *IO;
346: int ret = 0;
347:
348: if(pOS_ConstructMsgPort(&Port)) {
349: if((IO=(void*)pOS_CreateIORequest(&Port,sizeof(struct pOS_TrackdiskIO)))) {
350: if(!pOS_OpenDevice(dev_name, dev_unit,(struct pOS_IORequest*)IO,0,0)) {
351: struct pOS_DriveGeometry Geom;
352: char *buf;
353:
354: memset(&Geom,0,sizeof(struct pOS_DriveGeometry));
355: IO->tdio_Command = TDCMD_GetGeometry;
356: IO->tdio_Data = &Geom;
357: IO->tdio_Length = sizeof(struct pOS_DriveGeometry);
358: pOS_DoIO((struct pOS_IORequest*)IO);
359: if(IO->tdio_Error!=0) {
1.1.1.2 root 360: Geom.dg_SectorSize = 512;
1.1 root 361: Geom.dg_TotalSectors = 880*2;
362: }
363:
364: if((buf=pOS_AllocMem(Geom.dg_SectorSize,Geom.dg_BufMemType))) {
365: ULONG sec;
366: ret = 1;
367:
368: for(sec = 0; sec<Geom.dg_TotalSectors; ++sec) {
369: if((sec % Geom.dg_CylSectors) == 0) {
370: printf("Reading sector %d/%d (%02d%%) of %s unit %d \r",
1.1.1.2 root 371: sec, Geom.dg_TotalSectors,
1.1 root 372: (100*sec)/Geom.dg_TotalSectors, dev_name, dev_unit);
373: fflush(stdout);
374: }
1.1.1.2 root 375:
1.1 root 376: IO->tdio_Command = CMD_READ;
377: IO->tdio_Data = buf;
378: IO->tdio_Length = Geom.dg_SectorSize;
379: IO->tdio_LOffset = Geom.dg_SectorSize*sec;
380: pOS_DoIO((struct pOS_IORequest*)IO);
381: if(IO->tdio_Error) printf("Err. on\n");
382: if(fwrite(buf,1,Geom.dg_SectorSize,dst)!=Geom.dg_SectorSize) {
1.1.1.2 root 383: ret = 0;
1.1 root 384: break;
385: }
386: }
387: IO->tdio_Command = TDCMD_Motor;
388: IO->tdio_Length = 0;
389: pOS_DoIO((struct pOS_IORequest*)IO);
390: printf(" \r");
391: fflush(stdout);
1.1.1.2 root 392:
1.1 root 393: pOS_FreeMem(buf,Geom.dg_SectorSize);
394: }
395: pOS_CloseDevice((struct pOS_IORequest*)IO);
396: } pOS_DeleteIORequest((struct pOS_IORequest*)IO);
397: } pOS_DestructMsgPort(&Port);
398: }
399: return ret;
400: }
401:
402: /****************************************************************************/
403: /*
404: * Copy one raw disk to a file.
405: */
1.1.1.2 root 406: int readdevice(char *name, char *dst)
1.1 root 407: {
408: FILE *f = NULL;
409: char *device_name;
410: int device_unit;
411: int retstatus = 0;
412: #ifdef HAVE_SIGACTION
413: struct sigaction oldsa;
414: int oldsa_valid;
415: #endif
416: int inhibited;
417:
418: #ifdef HAVE_SIGACTION
419: /* disable break */
420: oldsa_valid = (0==sigaction(SIGINT, NULL, &oldsa));
421: signal(SIGINT, SIG_IGN); /* <--- gcc complains about something */
1.1.1.2 root 422: /* in there but I don't know why. */
1.1 root 423: #endif
424: /* get device name & unit */
425: extract_dev_unit(name, &device_name, &device_unit);
426:
427: if(device_name) {
1.1.1.2 root 428: /* if no destination then just check if the device exists */
429: if(dst == NULL)
430: retstatus = device_exists(device_name, device_unit);
431: else {
1.1 root 432: inhibited = dev_inhibit(name,1);
1.1.1.2 root 433: /* open dest file */
434: if((f = fopen(dst,"wb"))) {
435: retstatus = raw_copy(device_name, device_unit, f);
436: fclose(f);
437: }
1.1 root 438: if(inhibited) dev_inhibit(name,0);
1.1.1.2 root 439: }
440: free(device_name);
1.1 root 441: }
442:
443: #ifdef HAVE_SIGACTION
444: /* enable break */
445: if(oldsa_valid) sigaction(SIGINT, &oldsa, NULL);
446: #endif
447: return retstatus;
448: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.