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

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

unix.superglobalmegacorp.com

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