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