#include #include #include #include #include #include extern const char *__progname; static int dfd; static int ro; static void usage(void) { fprintf(stderr,"Usage: %s raw-disk-device\n",__progname); exit(1); } static void set4(void *dp, unsigned int v) { ((unsigned char *)dp)[0] = (v >> 24) & 0xff; ((unsigned char *)dp)[1] = (v >> 16) & 0xff; ((unsigned char *)dp)[2] = (v >> 8) & 0xff; ((unsigned char *)dp)[3] = v & 0xff; } static unsigned int get4(void *dp) { return( (((unsigned char *)dp)[0] * 0x01000000) + (((unsigned char *)dp)[1] * 0x00010000) + (((unsigned char *)dp)[2] * 0x00000100) + (((unsigned char *)dp)[3] * 0x00000001) ); } int main(int, char **); int main(int ac, char **av) { int opc; if (ac != 2) usage(); ro = 0; dfd = open(av[1],O_RDWR,0); if (dfd < 0) { ro = 1; dfd = open(av[1],O_RDONLY,0); if (dfd < 0) { fprintf(stderr,"%s: %s: %s\n",__progname,av[1],strerror(errno)); exit(1); } } while (1) { opc = getchar(); if (opc == EOF) exit(0); switch (opc) { case 'o': { int rwflag; int part; char rbuf[4]; rwflag = getchar(); if (rwflag == EOF) { fprintf(stderr,"%s: EOF reading open rwflag\n",__progname); exit(1); } part = getchar(); if (part == EOF) { fprintf(stderr,"%s: EOF reading open partition\n",__progname); exit(1); } switch (rwflag) { case 'r': set4(&rbuf[0],0); break; case 'w': case 'b': set4(&rbuf[0],ro?EROFS:0); break; default: fprintf(stderr,"%s: protocol error: invalid open flag 0x%02x\n",__progname,rwflag); exit(1); break; } write(1,&rbuf[0],4); } break; case 'c': break; case 'r': { unsigned int blkno; char rbuf[516]; int n; if (fread(&rbuf[0],1,4,stdin) != 4) { fprintf(stderr,"%s: can't get read sector #\n",__progname); exit(1); } blkno = get4(&rbuf[0]); n = pread(dfd,&rbuf[4],512,blkno*(off_t)512); if (n < 0) { set4(&rbuf[0],errno); } else if (n != 512) { set4(&rbuf[0],EIO); } else { set4(&rbuf[0],0); } write(1,&rbuf[0],516); } break; case 'w': { char wbuf[516]; unsigned int blkno; char rbuf[4]; int n; if (fread(&wbuf[0],1,516,stdin) != 516) { fprintf(stderr,"%s: can't get write packet\n",__progname); exit(1); } blkno = get4(&wbuf[0]); n = pwrite(dfd,&wbuf[4],512,blkno*(off_t)512); if (n < 0) { set4(&rbuf[0],errno); } else if (n != 512) { set4(&rbuf[0],EIO); } else { set4(&rbuf[0],0); } write(1,&rbuf[0],4); } break; case 'z': { unsigned int l; unsigned int h; unsigned int m; char resp[4]; static int ok(unsigned int b) { char junk[512]; return(pread(dfd,&junk[0],512,b*(off_t)512)==512); } l = 0; h = 1; while (ok(l)) { l = h; h <<= 1; } while (h-l > 1) { m = (h + l) >> 1; if (ok(m)) l = m; else h = m; } set4(&resp[0],h); write(1,&resp[0],4); } break; default: fprintf(stderr,"%s: protocol error: invalid command 0x%02x\n",__progname,opc); exit(1); break; } } }