Annotation of uae/src/od-pOS/pos-disk.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.