|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * pos-disk.c: Creates pseudo dev: handler. Copy tracks to rawfile ! 5: * (used in zfile.c). ! 6: * ! 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: /****************************************************************************/ ! 94: /* support routines to handle unix filename convention ! 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) { ! 108: *t++='/'; ! 109: while(*s!=':') *t++=*s++; ! 110: *t++='/';++s; ! 111: } ! 112: while(*s=='/') {*t++='.';*t++='.';*t++=*s++;} ! 113: while(*s) { ! 114: if(s[0]=='/' && s[1]=='/') {*t++=*s++;*t++='.';*t++='.';*t++=*s++;} ! 115: else *t++=*s++; ! 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=='/') { ! 131: ++s; ! 132: while(*s && *s!='/') *t++=*s++; ! 133: if(*s=='/') {*t++=':';++s;} ! 134: } ! 135: ! 136: while(*s) { ! 137: if(s[0]=='.' && s[1]=='.') s+=2; ! 138: else *t++=*s++; ! 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=='/') { ! 155: *file = my_strdup(s+1); ! 156: s[1] = '\0'; ! 157: *dir = my_strdup(src); ! 158: free(src); ! 159: } else { ! 160: *file = src; ! 161: *dir = my_strdup(""); ! 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 */ ! 190: lock = pOS_LockObject(NULL, amiga_dev_path, ! 191: FILELKACC_Shared|FILELKACC_NoReq); ! 192: if(!lock) { ! 193: char name[80]; ! 194: lock = pOS_LockObject(NULL, pseudo_dev_path, ! 195: FILELKACC_Shared|FILELKACC_NoReq); ! 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, ! 202: FILELKACC_Shared|FILELKACC_NoReq); ! 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)) { ! 208: pOS_UnlockObject(lock); ! 209: goto fail; ! 210: } ! 211: /* the lock is the assign now */ ! 212: pseudo_dev_assigned = 1; ! 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)) { ! 217: struct pOS_FileHandle *fd; ! 218: char name[80]; ! 219: ! 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;} ! 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]) { ! 238: char name[80]; ! 239: sprintf(name,"%sDF%d",amiga_dev_path,i); ! 240: pOS_DeleteObjectName(NULL, name); ! 241: dfx_done[i] = 0; ! 242: } ! 243: ! 244: if(pseudo_dev_assigned) { ! 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; ! 250: } ! 251: ! 252: if(pseudo_dev_created) { ! 253: pOS_DeleteObjectName(NULL, pseudo_dev_path); ! 254: pseudo_dev_created = 0; ! 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) { ! 271: if(!pOS_OpenDevice(device_name, device_unit, ! 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); ! 296: } ! 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; ! 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); ! 312: } ! 313: if(*dev_name) { ! 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: } ! 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) { ! 361: Geom.dg_SectorSize = 512; ! 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", ! 372: sec, Geom.dg_TotalSectors, ! 373: (100*sec)/Geom.dg_TotalSectors, dev_name, dev_unit); ! 374: fflush(stdout); ! 375: } ! 376: ! 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) { ! 384: ret = 0; ! 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); ! 393: ! 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: */ ! 407: int readdevice(char *name, char *dst) ! 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 */ ! 423: /* in there but I don't know why. */ ! 424: #endif ! 425: /* get device name & unit */ ! 426: extract_dev_unit(name, &device_name, &device_unit); ! 427: ! 428: if(device_name) { ! 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 { ! 433: inhibited = dev_inhibit(name,1); ! 434: /* open dest file */ ! 435: if((f = fopen(dst,"wb"))) { ! 436: retstatus = raw_copy(device_name, device_unit, f); ! 437: fclose(f); ! 438: } ! 439: if(inhibited) dev_inhibit(name,0); ! 440: } ! 441: free(device_name); ! 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.