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

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

unix.superglobalmegacorp.com

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