#include #include #include #include #include #include extern const char *__progname; static int dfd; static void usage(void) { fprintf(stderr,"Usage: %s pseudo-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) ); } static int dfdr(void *data, int len) { char *dp; int n; dp = data; while (len > 0) { n = read(dfd,dp,len); if (n <= 0) return(1); dp += n; len -= n; } return(0); } int main(int, char **); int main(int ac, char **av) { unsigned char opc; if (ac != 2) usage(); dfd = open(av[1],O_RDWR,0); if (dfd < 0) { fprintf(stderr,"%s: %s: %s\n",__progname,av[1],strerror(errno)); exit(1); } while (1) { if (dfdr(&opc,1)) exit(0); switch (opc) { case 'o': { unsigned char args[2]; char rbuf[4]; int err; if (dfdr(&args[0],2)) { fprintf(stderr,"%s: can't read open rwflag/part\n",__progname); exit(1); } switch (args[0]) { case 'r': case 'w': case 'b': putchar('o'); putchar(args[0]); putchar(args[1]); fflush(stdout); if (fread(&rbuf[0],1,4,stdin) != 4) { fprintf(stderr,"%s: can't read open reply\n",__progname); exit(1); } err = get4(&rbuf[0]); write(dfd,&err,sizeof(int)); break; default: fprintf(stderr,"%s: protocol error: invalid open flag 0x%02x\n",__progname,args[0]); exit(1); break; } } break; case 'c': putchar('c'); fflush(stdout); break; case 'r': { unsigned int blkno; char buf[516]; int err; if (dfdr(&blkno,sizeof(unsigned int))) { fprintf(stderr,"%s: can't get read sector #\n",__progname); exit(1); } set4(&buf[0],blkno); putchar('r'); fwrite(&buf[0],1,4,stdout); fflush(stdout); if (fread(&buf[0],1,516,stdin) != 516) { fprintf(stderr,"%s: can't read read reply\n",__progname); exit(1); } err = get4(&buf[0]); write(dfd,&err,sizeof(err)); write(dfd,&buf[4],512); } break; case 'w': { char buf[516]; unsigned int blkno; int err; if ( dfdr(&blkno,sizeof(unsigned int)) || dfdr(&buf[4],512) ) { fprintf(stderr,"%s: can't read write packet\n",__progname); exit(1); } set4(&buf[0],blkno); putchar('w'); fwrite(&buf[0],1,516,stdout); fflush(stdout); if (fread(&buf[0],1,4,stdin) != 4) { fprintf(stderr,"%s: can't read write reply\n",__progname); exit(1); } err = get4(&buf[0]); write(dfd,&err,sizeof(int)); } break; case 'z': { int sz; char resp[4]; putchar('z'); fflush(stdout); if (fread(&resp[0],1,4,stdin) != 4) { fprintf(stderr,"%s: can't read write reply\n",__progname); exit(1); } sz = get4(&resp[0]); write(dfd,&sz,sizeof(int)); } break; default: fprintf(stderr,"%s: protocol error: invalid command 0x%02x\n",__progname,opc); exit(1); break; } } }