/*----------------------------------------------------------------------*/ /* $Author: zellan $ */ /* $Date: 2000/12/04 10:33:47 $ */ /* $Id: unwrap.c,v 1.2 2000/12/04 10:33:47 zellan Exp $ */ /* $Revision: 1.2 $ */ /* $RCSfile: unwrap.c,v $ */ /* $Source: /jcn/CVS/tools/plan9/unwrap/unwrap.c,v $ */ /* $Name: $ */ /* $State: Exp $ */ /*----------------------------------------------------------------------*/ static char rcsid[] = "$Id: unwrap.c,v 1.2 2000/12/04 10:33:47 zellan Exp $"; #include #include #include #define BUFFER_SIZE 2048 #define TYPE_DIR 2 #define TYPE_FILE 0 #define STATE_GETNAME 0 #define STATE_GETACCESS 1 #define STATE_GETGROUP 2 #define STATE_GETUSER 3 #define STATE_GETNUMBER 4 #define STATE_GETSIZE 5 #define STATE_CREATE 6 char InFileName[1024]; char OutPathName[1024]; long pos = 0; int InFile = 0; int OutPath = 0; int InFd = 0; int OutFd = 0; unsigned char inBuffer[BUFFER_SIZE+1]; unsigned char outBuffer[BUFFER_SIZE+1]; int inPtr; int inLeft; int verbose = 0; int skip = 0; int table = 0; int skiperr = 0; /* function prototypes */ int unwrap(void); int inCh(void); void Usage(void); int WriteFile(int fd, long len); /*----------------------------------------------------------------------*/ /* main */ /*----------------------------------------------------------------------*/ int main(int argc, char **argv) { *argv++; argc--; while(argc--) { if((*argv)[0] == '-') { switch((*argv)[1]) { case 'v': verbose = 1; break; case 't': table = 1; break; #if(0) case 'd': case 'D': (*argv) += 2; sscanf((*argv), "%x", &tmp); debug = tmp; printf("tmp %04x sc_debug %04x\n", tmp, sc_debug); break; #endif case 'k': skip = 1; break; case 'h': case 'H': case '?': default: Usage(); exit(0); } } else { if(!InFile) { strcpy(InFileName, *argv); InFile = 1; } else { if(!OutPath) { strcpy(OutPathName, *argv); OutPath = 1; } } } *argv++; } if(InFile && (OutPath || table)) { InFd = open(InFileName, O_RDONLY | O_BINARY, 0); if(InFd < 0) { fprintf(stderr, "Error(%d) opening %s\n", errno, InFileName); exit(0); } } else { Usage(); exit(0); } if(!(strlen(OutPathName) == 1 && OutPathName[0] != '.') && !table) { if(mkdir(OutPathName, 0777) == -1) { if(errno != EEXIST) { fprintf(stderr, "mkdir failed (%d) ->%s<-\n", errno, OutPathName); close(InFd); exit(0); } } } fprintf(stderr, "exit %ld ", unwrap()); fprintf(stderr, "pos %d \n", pos); close(InFd); } /* main */ /*----------------------------------------------------------------------*/ /* unwrap */ /*----------------------------------------------------------------------*/ int unwrap(void) { int ch; int state; char dir[1024]; char name[1024]; char file[1024]; char access[12]; char user[33]; char group[33]; char number[33]; char size[33]; int len; int type; state = STATE_GETNAME; while(1) { switch(state) { case STATE_GETNAME: if(gettoken(&name)) { state = STATE_GETACCESS; skiperr = 0; } else return(1); break; case STATE_GETACCESS: if(gettoken(&access)) { state = STATE_GETGROUP; if(strlen(access) == 11) type = TYPE_DIR; else type = TYPE_FILE; } else return(2); break; case STATE_GETGROUP: if(gettoken(&group)) { state = STATE_GETUSER; } else return(3); break; case STATE_GETUSER: if(gettoken(&user)) { state = STATE_GETNUMBER; } else return(4); break; case STATE_GETNUMBER: if(gettoken(&number)) { state = STATE_GETSIZE; } else return(5); break; case STATE_GETSIZE: if(gettoken(&size)) { state = STATE_CREATE; sscanf(size, "%ld", &len); } else return(6); break; case STATE_CREATE: switch(type) { case TYPE_DIR: if(len) return(9); if(table) break; strcpy(dir, OutPathName); strcat(dir, name); if(mkdir(dir, 0777) == -1) { if(errno != EEXIST) { fprintf(stderr, "mkdir failed (%d) ->%s<-\n", errno, dir); if(!skip) { close(InFd); exit(0); } } } break; case TYPE_FILE: if(table) { lseek(InFd, len, SEEK_CUR); } else { strcpy(dir, OutPathName); strcat(dir, name); OutFd = open(dir, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0777); if(OutFd < 0) { fprintf(stderr, "Error(%d) opening %s\n", errno, dir); if(skip) { skiperr = 1; } else { close(InFd); exit(0); } } if(!WriteFile(OutFd, len)) return(7); if(skiperr) break; close(OutFd); } break; } if(table || verbose) { if(type == TYPE_FILE) printf("f %s", name); else printf("d %s", name); printf(" len=%d", len); printf(" access=%d", access); printf("\n"); } state = STATE_GETNAME; break; } } } /* unwrap */ /*----------------------------------------------------------------------*/ /* WriteFile */ /*----------------------------------------------------------------------*/ int WriteFile(int fd, long len) { long l; while(len > 0) { if(len >= BUFFER_SIZE) l = BUFFER_SIZE; else l = len; if(read(InFd, outBuffer, l) != l) { fprintf(stdout, "error reading input file %d\n", pos); return(0); } pos += l; if(!skiperr) write(fd, outBuffer, l); len -= l; } return(1); } /* WriteFile */ /*----------------------------------------------------------------------*/ /* gettoken */ /*----------------------------------------------------------------------*/ int gettoken(char *token) { int ch; char *p; p = token; while(1) { ch = inCh(); switch(ch) { case -1: return(0); case ' ': case '\n': case '\r': *p = '\0'; return(1); default: *p++ = ch; break; } } } /* gettoken */ /*----------------------------------------------------------------------*/ /* inCh */ /*----------------------------------------------------------------------*/ int inCh(void) { char b[2]; if(read(InFd, b, 1) != 1) return(-1); else { pos++; return(b[0]); } } /* inCh */ /*----------------------------------------------------------------------*/ /* Usage */ /*----------------------------------------------------------------------*/ void Usage(void) { fprintf(stdout, "\n"); fprintf(stdout, "unwrap [options] \n"); fprintf(stdout, "options: \n"); fprintf(stdout, " k - skip errors\n"); fprintf(stdout, " t - print filenames only\n"); fprintf(stdout, " v - verbose\n"); fprintf(stdout, "\n"); } /* Usage */ /* EOF unwrap.c */