static int charliteral(int c) { if(!bCanInsertSymbol) { //maks: solve the error when colorize "oi/oi" WASLITERAL = 0; return c; } if (c == '\\') { switch ((c = EiC_nextchar())) { case 'n': c = '\n'; break; /* newline */ case 't': c = '\t'; break; /* tabspace */ case 'v': c = '\v'; break; /* vertical tab */ case 'b': c = '\b'; break; /* backspace */ case 'r': c = '\r'; break; /* carriage return */ case 'f': c = '\f'; break; /* formfeed */ case 'a': c = '\a'; break; /* bell */ case '\\': c = '\\'; break; /* backslash */ case '\'': c = '\''; break; /* single quote */ case '"': c = '\"'; break; /* double quote */ case '?': c = '\?'; break; /* question mark */ case 'x': /* string of hex characters */ case 'X':{ int i, val = 0; while ((i = gethex((c = EiC_nextchar()))) > -1) { val = val * 16 + i; } retract(c); if (val > 255) EiC_error("Illegal character hex value"); c = val; } break; default: if (getoct(c) > -1) { /* octal characters */ int i, val = 0; while ((i = getoct(c)) > -1) { val = val * 8 + i; c = EiC_nextchar(); } retract(c); if (val > 255) EiC_error("Illegal character octal value"); c = val; } else EiC_error("Illegal character escape sequence `\\%c'", c); break; } WASLITERAL = 1; } else WASLITERAL = 0; return ((signed char )c); }
int getchr () { int c, n; switch (c = getchar ()) { default: return (c); case '\n': return (' '); case '\\': break; case 's': case 'S': n = getchar (); if (n!='p' && n!='P') { ungetc (n, stdin); return (c); } if (((c=getchar())=='a' || c=='A') && ((c=getchar())=='c' || c=='C') && ((c=getchar())=='e' || c=='E')) return (' '); fatal ("invalid #\\space constant"); case 'n': case 'N': n = getchar (); if (n!='e' && n!='E') { ungetc (n, stdin); return (c); } if (((c=getchar())=='w' || c=='W') && ((c=getchar())=='l' || c=='L') && ((c=getchar())=='i' || c=='I') && ((c=getchar())=='n' || c=='N') && ((c=getchar())=='e' || c=='E')) return ('\n'); fatal ("invalid #\\newline constant"); } switch (c = getchar ()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': return (getoct (c)); case '\n': return (' '); case 'n': return ('\n'); case 't': return ('\t'); case 'r': return ('\r'); case 'b': return ('\b'); case 'f': return ('\f'); } return (c); }
void populate(char *name) { int64_t offset; int32_t isabs, magic, namesize, mode; Fileinf f; tapefile = open(name, OREAD); if (tapefile<0) error("Can't open argument file"); replete = 1; for (offset = 0;;) { seek(tapefile, offset, 0); if (read(tapefile, (char *)&dblock.dbuf, TBLOCK)<TBLOCK) break; magic = getoct(dblock.dbuf.magic, sizeof(dblock.dbuf.magic)); if (magic != 070707){ print("%lo\n", magic); error("out of phase--get help"); } if (dblock.nbuf.name[0]=='\0' || strcmp(dblock.nbuf.name, "TRAILER!!!")==0) break; mode = getoct(dblock.dbuf.mode, sizeof(dblock.dbuf.mode)); f.mode = mode&0777; switch(mode & 0170000) { case 0040000: f.mode |= DMDIR; break; case 0100000: break; default: f.mode = 0; break; } f.uid = getoct(dblock.dbuf.uid, sizeof(dblock.dbuf.uid)); f.gid = getoct(dblock.dbuf.gid, sizeof(dblock.dbuf.gid)); f.size = getoct(dblock.dbuf.size, sizeof(dblock.dbuf.size)); f.mdate = getoct(dblock.dbuf.mtime, sizeof(dblock.dbuf.mtime)); namesize = getoct(dblock.dbuf.namesize, sizeof(dblock.dbuf.namesize)); f.addr = offset+sizeof(struct header)+namesize; isabs = dblock.nbuf.name[0]=='/'; f.name = &dblock.nbuf.name[isabs]; poppath(f, 1); offset += sizeof(struct header)+namesize+f.size; } }
/* returns 0 on failed checksum, nonzero if probably ok it was noted that some versions of tar compute signed chksums, though unsigned appears to be the standard; chksum is simple sum of all bytes in header as integers (using at least 17 bits) with chksum values treated as ASCII spaces. */ int valid_checksum(struct tar_header *header) { unsigned hdrchksum = (unsigned)getoct(header->chksum,8); signed schksum = 0; unsigned uchksum = 0; int i; for (i=0; i < sizeof(struct tar_header); i++) { unsigned char val = ((unsigned char *)header)[i]; if ((i >= 148) && (i < 156)) /* chksum */ { val = ' '; } schksum += (signed char)val; uchksum += val; } if (hdrchksum == uchksum) return 1; if ((int)hdrchksum == schksum) return 2; return 0; }
int tar_extract_all( TAR *t, char *prefix ) { union tar_buffer buffer; int len, err, getheader = 1, remaining = 0; FILE *outfile = NULL; char fname[BLOCKSIZE + PATH_MAX]; while( 1 ) { len = gzread( *t, &buffer, BLOCKSIZE ); if( len < 0 ) { fprintf( stderr, "%s\n", gzerror(*t, &err) ); } /* * Always expect complete blocks to process * the tar information. */ if( len != 0 && len != BLOCKSIZE ) { fprintf( stderr, "gzread: incomplete block read\n" ); return -1; } /* * If we have to get a tar header */ if( getheader == 1 ) { /* * If we met the end of the tar * or the end-of-tar block, we are done */ if( (len == 0) || (buffer.header.name[0] == 0) ) { break; } sprintf( fname, "%s/%s", prefix, buffer.header.name ); /* Check magic value in header */ if( strncmp( buffer.header.magic, "GNUtar", 6 ) && strncmp( buffer.header.magic, "ustar", 5 ) ) { //fprintf(stderr, "not a tar file\n"); return -1; } switch( buffer.header.typeflag ) { case DIRTYPE: makedir( fname ); break; case REGTYPE: case AREGTYPE: remaining = getoct( buffer.header.size, 12 ); if( !remaining ) outfile = NULL; else { outfile = fopen( fname, "wb" ); if( outfile == NULL ) { /* try creating directory */ char *p = strrchr( fname, '/' ); if( p != NULL ) { *p = '\0'; makedir( fname ); *p = '/'; outfile = fopen( fname, "wb" ); if( !outfile ) { fprintf( stderr, "tar couldn't create %s\n", fname ); } } } } /* * could have no contents */ getheader = (remaining) ? 0 : 1; break; default: break; } } else { unsigned int bytes = (remaining > BLOCKSIZE)?BLOCKSIZE:remaining; if( outfile != NULL ) { if( fwrite( &buffer, sizeof(char), bytes, outfile ) != bytes ) { fprintf( stderr, "error writing %s skipping...\n", fname ); fclose( outfile ); outfile = NULL; unlink( fname ); } } remaining -= bytes; if( remaining == 0 ) { getheader = 1; if( outfile != NULL ) { fclose(outfile); outfile = NULL; } } } } return 0; }
extern int EiC_lexan(void) { int t=0, loop; char c=0, EiC_nextchar(); #ifdef ILOOKAHEAD token = &EiC_TokenArray[EiC_TokenP]; if(EiC_TokenR > 0) { EiC_TokenR--; EiC_TokenI++; EiC_TokenP=(EiC_TokenP+1)%MAX_TOKENS; return token->Tok; } #else if (STOKEN != NOTOKEN) { STOKEN = NOTOKEN; return token->Tok; } #endif loop = 1; state = 0; while (loop) { switch (state) { case 0: lex_lastpos = lex_curpos; c = EiC_nextchar(); state = (WHITE(c) ? 0 : (c == '\n' ? lex_lineno++, 0 : (c == '<' ? t = LT, 1 : (c == '>' ? t = GT, 2 : (c == '+' ? t = '+', 3 : (c == '-' ? t = '-', 4 : (c == '|' ? t = BOR, 5 : (c == '&' ? t = AND, 6 : (c == '\''? 7 : (c == '"' ? 8 : (c == '.' ? 9 : (c == '/' ? t = '/', c = EiC_nextchar(), 50 : (c == '%' ? t = '%', c = EiC_nextchar(), 50 : (c == '*' ? t = '*', c = EiC_nextchar(), 50 : (c == '=' ? t = ASS, c = EiC_nextchar(), 50 : (c == '!' ? t = NOT, c = EiC_nextchar(), 50 : (c == '^' ? t = XOR, c = EiC_nextchar(), 50 : //(c == '~' ? t = NOTB, c = EiC_nextchar(), 50 : //maks: ~ fail(RELOP, c)))))))))))))))))); break; case 1: /* get <, <= and << */ if ((c = EiC_nextchar()) == '<') t = LSHT; else state = 50; break; case 2: /* get >, >= and >> */ if ((c = EiC_nextchar()) == '>') t = RSHT; else state = 50; break; case 3: c = EiC_nextchar(); /* get +, += or ++ */ if (c == '+') t = INC, state = 60; else state = 50; break; case 4: c = EiC_nextchar(); /* get -, -= -- */ state = 60; if (c == '-') t = DEC; else if (c == '>') t = RARROW; else state = 50; break; case 5: c = EiC_nextchar(); /* get |, |= or || */ if (c == '|') t = LOR, state = 60; else state = 50; break; case 6: c = EiC_nextchar(); /* get &, &= or && */ if (c == '&') t = LAND, state = 60; else state = 50; break; case 7:token->Val.ival = charliteral(EiC_nextchar()); /* char_constants */ t = TOKEN_CHAR; if (EiC_nextchar() != '\'') EiC_error("Missing single quote '"); state = 60; break; case 8: EiC_stringliteral(); /* string literals */ token->Tok = STR; /*return STR;*/ loop = 0; break; case 9: c = EiC_nextchar(); t = '.'; if(DIGIT(c)) state = 22; else state = 60; retract(c); break; case 10: c = EiC_nextchar(); /* identifiers and keywords */ state = (LETTER(c) ? 11 : (c == '_' ? 11 : fail(ID, c))); break; case 11: c = EiC_nextchar(); state = (LETTER(c) ? 11 : (DIGIT(c) ? 11 : (c == '_' ? 11 : 12))); break; case 12: retract(c); success(ID); /*return (token->Tok);*/ loop = 0; break; case 20: c = EiC_nextchar(); /* integers and reals */ state = (c == '0' ? 30 : (DIGIT(c) ? 21 : fail(TOKEN_INT, c))); break; case 21: c = EiC_nextchar(); state = (DIGIT(c) ? 21 : (c == '.' ? 22 : (c == 'e' ? 23 : (c == 'E' ? 23 : 25)))); break; case 22: c = EiC_nextchar(); state = (DIGIT(c) ? 22 : (c == 'e' ? 23 : (c == 'E' ? 23 : 26))); break; case 23: c = EiC_nextchar(); state = (c == '+' ? 24 : (c == '-' ? 24 : (DIGIT(c) ? 24 : fail(TOKEN_FLOAT, c) /* ??? */ ))); break; case 24: c = EiC_nextchar(); state = (DIGIT(c) ? 24 : 26); break; case 25: checkExt(c); success(TOKEN_INT); /*return (token->Tok);*/ loop = 0; break; case 26: checkExt(c); success(TOKEN_FLOAT); /*return (token->Tok);*/ loop = 0; break; case 27: checkExt(c); success(HEX); /*return (token->Tok);*/ loop = 0; break; case 28: checkExt(c); success(OCTAL); /*return (token->Tok);*/ loop = 0; break; case 30: /* check for octal and hex numbers */ if ((c = EiC_nextchar()) == 'x' || c == 'X') { while (gethex((c = EiC_nextchar())) > -1); state = 27; break; } if (c != '.' && c != 'e' && c != 'E') { while (getoct(c) > -1) c = EiC_nextchar(); state = 28; break; } retract(c); state = 21; break; case 50: /* mix with equal's */ if (c == '=') switch (t) { case '+': t = ADDEQ; break; /* += */ case '-': t = SUBEQ; break; /* -= */ case '/': t = DIVEQ; break; /* /= */ case '*': t = MULEQ; break; /* *= */ case '%': t = MODEQ; break; /* %= */ case ASS: t = EQ; break; /* == */ case GT: t = GE; break; /* >= */ case LT: t = LE; break; /* <= */ case NOT: t = NE; break; /* != */ case RSHT:t = RSHTEQ; break; /* >>= */ case LSHT:t = LSHTEQ; break; /* <<= */ case AND: t = ANDEQ; break; /* &= */ case BOR: t = BOREQ; break; /* |= */ case XOR: t = XOREQ; break; /* ^= */ //case NOTB: t = NOTBEQ; break; /* maks ~= */ default: retract(c); } else if(c == '/' && t == '/') //maks { //C++ comment //Only for colorize //Comments are removed by preprocessor before parser do { c = EiC_nextchar(); } while(c && c != '\n'); retract(c); success(MISC); token->Tok = TOKEN_COMMENT; loop = 0; break; } else retract(c); state = 60; break; case 60: success(MISC); token->Tok = t; /*return (token->Tok);*/ loop = 0; break; case 100: token->Tok = EiC_nextchar(); /*return (token->Tok);*/ loop = 0; break; } } #ifdef ILOOKAHEAD if(EiC_TokenI<MAX_TOKENS) EiC_TokenI++; EiC_TokenP = (EiC_TokenP +1)%MAX_TOKENS; #endif return token->Tok; }
static void success(int ival) { int i, size; size = (int) (lex_curpos - lex_lastpos); memcpy(EiC_LEXEM, &lex_buff[lex_lastpos], size); EiC_LEXEM[size] = '\0'; if (Lseen) size--; if (Useen) size--; if (Fseen) size--; Hseen = 0; switch (ival) { case ID: if ((token->Tok = EiC_iskeyword(cwords, EiC_LEXEM, sizeof(cwords) / sizeof(keyword_t))) == 0) { if(size > 64) //maks: avoid crash when enter a very long identifier { EiC_error("Identifier is too large"); return; } token->Tok = ID; /* search for id in various name spaces */ if ((token->Val.sym = EiC_lookup(EiC_work_tab, EiC_LEXEM)) == NULL) if(bCanInsertSymbol) token->Val.sym = EiC_insertLUT(EiC_work_tab, EiC_LEXEM, ID); //maks if (token->Val.sym) if (token->Val.sym->sclass == c_typedef) token->Tok = TYPENAME; } break; case OCTAL: if (Fseen) EiC_error("Declaration syntax error"); for (lexival = 0, i = 0; i < size; i++) lexival = lexival * 8 + getoct(EiC_LEXEM[i]); Hseen = 1; setintval(); break; case HEX: for (lexival = 0, i = 2; i < size; i++) lexival = lexival * 16 + gethex(EiC_LEXEM[i]); Hseen = 1; setintval(); break; case TOKEN_INT: for (lexival = 0, i = 0; i < size; i++) lexival = lexival * 10 + EiC_LEXEM[i] - '0'; setintval(); break; case TOKEN_FLOAT: if (Useen) EiC_error("Declaration syntax error"); lexfval = atof(EiC_LEXEM); setfloatval(); break; case RELOP: case MISC: break; } }
/* return 0 on success * extract a file in tarball to appropriate directory, ignoring any paths in archive * note that szDestPath lacks slash at end * szFName is the file to extract * szWantedFile is the file to extract * szDestPath is the path to extract to (without trailing slash) - if NULL, extracted data wont be saved to disk * retBuf is a pointer to a bufferpointer - will be g_try_malloc'ed and filled with data if retBuf != NULL * retFileSize will be filled with the size of the file, if it's != NULL * * extraction routines derived from logic in zlib's contrib untgz.c program */ int UT_untgz(const char *szFName, const char *szWantedFile, const char *szDestPath, char **retBuf, int *retFileSize) { gzFile tarball; union tar_buffer buffer; int getheader = 1; int remaining = 0; int len; char fname[TGZ_BLOCKSIZE]; FILE *outfile = NULL; int fileSize = 0; if (retBuf) FREEP(*retBuf); if ((tarball = gzopen(szFName, "rb")) == NULL) { UT_DEBUGMSG(("untgz: Error while opening downloaded dictionary archive")); return 1; } bool done = false; while (!done) { if ((len = gzread(tarball, &buffer, TGZ_BLOCKSIZE)) != TGZ_BLOCKSIZE) { // error (gzerror(in, &err)); UT_DEBUGMSG(("untgz: gzread failed to read in complete block")); gzclose(tarball); return 1; } /* * If we have to get a tar header */ if (getheader == 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ if ((len == 0) || (buffer.header.name[0]== 0)) { done = true; continue; } // tartime = static_cast<time_t>(getoct(buffer.header.mtime,12)); strcpy(fname, buffer.header.name); strippath(fname); if ((buffer.header.typeflag == '\0') || // [A]REGTYPE, ie regular files (buffer.header.typeflag == '0') ) { remaining = getoct(buffer.header.size, 12); if ((remaining) && (g_ascii_strcasecmp(fname, szWantedFile) == 0)) { fileSize = remaining; if (retBuf) { if (!(*retBuf = static_cast<char *>(g_try_malloc(fileSize)))) *retBuf = NULL; } if (retFileSize) *retFileSize = fileSize; if (szDestPath) { UT_String outfilename(szDestPath); outfilename += "/"; outfilename += fname; if ((outfile = fopen(outfilename.c_str(), "wb")) == NULL) { UT_DEBUGMSG(("untgz: Unable to save %s", outfilename.c_str())); } } else outfile = NULL; } else outfile = NULL; /* * could have no contents */ getheader = (remaining) ? 0 : 1; } } else // if (getheader != 1) { unsigned int bytes = (remaining > TGZ_BLOCKSIZE) ? TGZ_BLOCKSIZE : remaining; if (retBuf && *retBuf) { memcpy(retBuf[fileSize - remaining], buffer.buffer, bytes); } if (outfile != NULL) { if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) { UT_DEBUGMSG(("untgz: error writing, skipping %s", fname)); fclose(outfile); g_unlink(fname); } } remaining -= bytes; if (remaining == 0) { getheader = 1; if (outfile != NULL) { // TODO: should actually set proper time from archive, oh well fclose(outfile); outfile = NULL; } } } // if (getheader == 1) else end } if (tarball != NULL) gzclose(tarball); return 0; }
int funTar (DataSource *src, int action, int arg, int argc, char **argv, TarCallbackFun cb, void *data) { union tar_buffer buffer; int len; int err; int getheader = 1; int remaining = 0; FILE *outfile = NULL; char fname[BLOCKSIZE]; int tarmode; time_t tartime; struct attr_item *attributes = NULL; int ctr = 0; int extracting = 0; while (1) { ctr++; len = src->read(src->data, &buffer, BLOCKSIZE, src); if (len < 0) error(src->throwError(src->data, &err, src)); /* * Always expect complete blocks to process * the tar information. */ if (len != BLOCKSIZE) { action = TGZ_INVALID; /* force error exit */ remaining = 0; /* force I/O cleanup */ } /* * If we have to get a tar header */ if (getheader >= 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ if (len == 0 || buffer.header.name[0] == 0) break; tarmode = getoct(buffer.header.mode,8); tartime = (time_t)getoct(buffer.header.mtime,12); if (tarmode == -1 || tartime == (time_t)-1) { buffer.header.name[0] = 0; action = TGZ_INVALID; } if (getheader == 1) { strncpy(fname,buffer.header.name,SHORTNAMESIZE); extracting = 0; if (fname[SHORTNAMESIZE-1] != 0) fname[SHORTNAMESIZE] = 0; } else { /* * The file name is longer than SHORTNAMESIZE */ if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) error("bad long name"); getheader = 1; } /* * Act according to the type flag */ switch (buffer.header.typeflag) { case DIRTYPE: if (action == TGZ_LIST) { cb(ctr, DIRTYPE, tartime, fname, remaining, data); /* printf(" %s <dir> %s\n",strtime(&tartime),fname); */ } else if (action == TGZ_EXTRACT) { /* makedir(fname); */ extracting = 0; push_attr(&attributes,fname,tarmode,tartime); } break; case REGTYPE: case AREGTYPE: remaining = getoct(buffer.header.size,12); if (remaining == -1) { action = TGZ_INVALID; break; } if (action == TGZ_LIST) { cb(ctr, buffer.header.typeflag, tartime, fname, remaining, data); /* printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); */ } else if (action == TGZ_EXTRACT) { extracting = matchname(arg,argc,argv,fname); } getheader = 0; break; case GNUTYPE_LONGLINK: case GNUTYPE_LONGNAME: remaining = getoct(buffer.header.size,12); if (remaining < 0 || remaining >= BLOCKSIZE) { action = TGZ_INVALID; break; } len = src->read(src->data, fname, BLOCKSIZE, src); if (len < 0) error(src->throwError(src->data, &err, src)); if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining) { action = TGZ_INVALID; break; } getheader = 2; break; default: if (action == TGZ_LIST) { cb(ctr, '\0', tartime, fname, remaining, data); /* printf(" %s <---> %s\n",strtime(&tartime),fname); */ } break; } } else { unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; if(extracting && action == TGZ_EXTRACT) ((TarExtractCallbackFun ) cb)(fname, buffer.buffer, bytes, remaining, data); remaining -= bytes; } if (remaining == 0) { getheader = 1; if(extracting && action == TGZ_EXTRACT) /* Close this file. */ ((TarExtractCallbackFun ) cb)(fname, NULL, 0, remaining, data); if (action != TGZ_INVALID) push_attr(&attributes,fname,tarmode,tartime); } /* * Abandon if errors are found */ if (action == TGZ_INVALID) { error("broken archive"); break; } } /* * Restore file modes and time stamps */ restore_attr(&attributes); return 0; }
/* Tar file extraction * gzFile in, handle of input tarball opened with gzopen * int cm, compressionMethod * int junkPaths, nonzero indicates to ignore stored path (don't create directories) * enum KeepMode keep, indicates to perform if file exists * int iCnt, char *iList[], argv style list of files to extract, {0,NULL} for all * int xCnt, char *xList[], argv style list of files NOT to extract, {0,NULL} for none * int failOnHardLinks, if nonzero then will treat failure to create a hard link same as * failure to create a regular file, 0 prints a warning if fails - note that hardlinks * will always fail on Windows prior to NT 5 (Win 2000) or later and non NTFS file systems. * * returns 0 (or positive value) on success * returns negative value on error, where * -1 means error reading from tarball * -2 means error extracting file from tarball * -3 means error creating hard link */ int tgz_extract(gzFile in, int cm, int junkPaths, enum KeepMode keep, int iCnt, TCHAR *iList[], int xCnt, TCHAR *xList[], int failOnHardLinks) { int getheader = 1; /* assume initial input has a tar header */ HANDLE outfile = INVALID_HANDLE_VALUE; union tar_buffer buffer; unsigned long remaining; TCHAR fname[BLOCKSIZE]; /* must be >= BLOCKSIZE bytes */ time_t tartime; /* do any prep work for extracting from compressed TAR file */ if (cm_init(in, cm)) { PrintMessage(_T("tgz_extract: unable to initialize decompression method.")); cm_cleanup(cm); return -1; } while (1) { if (readBlock(cm, &buffer) < 0) return -1; /* * If we have to get a tar header */ if (getheader >= 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ if (/* (len == 0) || */ (buffer.header.name[0]== 0)) break; /* compute and check header checksum, support signed or unsigned */ if (!valid_checksum(&(buffer.header))) { PrintMessage(_T("tgz_extract: bad header checksum")); cm_cleanup(cm); return -1; } /* store time, so we can set the timestamp on files */ tartime = (time_t)getoct(buffer.header.mtime,12); /* copy over filename chunk from header, avoiding overruns */ if (getheader == 1) /* use normal (short or posix long) filename from header */ { /* NOTE: prepends any prefix, including separator, and ensures terminated */ memset(fname, 0, sizeof(fname)); getFullName(&buffer, fname); } else /* use (GNU) long filename that preceeded this header */ { #if 0 /* if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) */ char fs[SHORTNAMESIZE]; /* force strings to same max len, then compare */ lstrcpyn(fs, fname, SHORTNAMESIZE); fs[SHORTNAMESIZE-1] = '\0'; buffer.header.name[SHORTNAMESIZE-1] = '\0'; if (lstrcmp(fs, buffer.header.name) != 0) { PrintMessage(_T("tgz_extract: mismatched long filename")); cm_cleanup(cm); return -1; } #else PrintMessage(_T("tgz_extract: using GNU long filename [%s]"), fname); #endif } /* LogMessage("buffer.header.name is:"); LogMessage(fname); */ switch (buffer.header.typeflag) { case DIRTYPE: dirEntry: if (!junkPaths) { safetyStrip(fname); makedir(fname); } break; case LNKTYPE: /* hard link */ case CONTTYPE: /* contiguous file, for compatibility treat as normal */ case REGTYPE: case AREGTYPE: /* Note: a file ending with a / may actually be a BSD tar directory entry */ if (fname[strlen(fname)-1] == '/') goto dirEntry; remaining = getoct(buffer.header.size,12); if ( /* add (remaining > 0) && to ignore 0 zero byte files */ ( (iList == NULL) || (matchname(fname, iCnt, iList, junkPaths)) ) && (!matchname(fname, xCnt, xList, junkPaths)) ) { if (!junkPaths) /* if we want to use paths as stored */ { /* try creating directory */ TCHAR *p = tstrrchr(fname, '/'); if (p != NULL) { *p = '\0'; makedir(fname); *p = '/'; } } else { /* try ignoring directory */ TCHAR *p = tstrrchr(fname, '/'); if (p != NULL) { /* be sure terminating '\0' is copied and */ /* use ansi memcpy equivalent that handles overlapping regions */ MoveMemory(fname, p+1, (strlen(p+1) + 1) * sizeof(TCHAR) ); } } if (*fname) /* if after stripping path a fname still exists */ { /* Attempt to open the output file and report action taken to user */ const TCHAR szERRMsg[] = _T("Error: Could not create file "), szSUCMsg[] = _T("Writing "), szSKPMsg[] = _T("Skipping "); const TCHAR * szMsg = szSUCMsg; safetyStrip(fname); if (buffer.header.typeflag == LNKTYPE) { outfile = INVALID_HANDLE_VALUE; /* create a hardlink if possible, else produce just a warning unless failOnHardLinks is true */ if (!MakeHardLink(fname, buffer.header.linkname)) { PrintMessage(_T("Warning: unable to create hard link %s [%d]"), fname, GetLastError()); if (failOnHardLinks) { cm_cleanup(cm); return -3; } } else { outfile = CreateFile(fname,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); goto setTimeAndCloseFile; } } else { /* Open the file for writing mode, creating if doesn't exist and truncating if exists and overwrite mode */ outfile = CreateFile(fname,GENERIC_WRITE,FILE_SHARE_READ,NULL,(keep==OVERWRITE)?CREATE_ALWAYS:CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); /* failed to open file, either valid error (like open) or it already exists and in a keep mode */ if (outfile == INVALID_HANDLE_VALUE) { /* if skip existing or only update existing and failed to open becauses exists */ if ((keep!=OVERWRITE) && (GetLastError()==ERROR_FILE_EXISTS)) { /* assume skipping initially (mode==SKIP or ==UPDATE with existing file newer) */ szMsg = szSKPMsg; /* and update output message accordingly */ /* if in update mode, check filetimes and reopen in overwrite mode */ if (keep == UPDATE) { FILETIME ftm_a; HANDLE h; WIN32_FIND_DATA ffData; cnv_tar2win_time(tartime, &ftm_a); /* archive file time */ h = FindFirstFile(fname, &ffData); /* existing file time */ if (h!=INVALID_HANDLE_VALUE) FindClose(h); /* cleanup search handle */ else goto ERR_OPENING; /* compare date+times, is one in tarball newer? */ if (*((LONGLONG *)&ftm_a) > *((LONGLONG *)&(ffData.ftLastWriteTime))) { outfile = CreateFile(fname,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if (outfile == INVALID_HANDLE_VALUE) goto ERR_OPENING; szMsg = szSUCMsg; } } } else /* in overwrite mode or failed for some other error than exists */ { ERR_OPENING: PrintMessage(_T("%s%s [%d]"), szERRMsg, fname, GetLastError()); cm_cleanup(cm); return -2; } } /* Inform user of current extraction action (writing, skipping file XYZ) */ PrintMessage(_T("%s%s"), szMsg, fname); } } } else outfile = INVALID_HANDLE_VALUE; /* * could have no contents, in which case we close the file and set the times */ if (remaining > 0) getheader = 0; else { setTimeAndCloseFile: getheader = 1; if (outfile != INVALID_HANDLE_VALUE) { FILETIME ftm; cnv_tar2win_time(tartime, &ftm); SetFileTime(outfile,&ftm,NULL,&ftm); CloseHandle(outfile); outfile = INVALID_HANDLE_VALUE; } } break; case GNUTYPE_LONGLINK: case GNUTYPE_LONGNAME: { remaining = getoct(buffer.header.size,12); if (readBlock(cm, fname) < 0) return -1; fname[BLOCKSIZE-1] = '\0'; if ((remaining >= BLOCKSIZE) || ((unsigned)strlen(fname) > remaining)) { PrintMessage(_T("tgz_extract: invalid long name")); cm_cleanup(cm); return -1; } getheader = 2; break; } default: /* if (action == TGZ_LIST) printf(" %s <---> %s\n",strtime(&tartime),fname); */ break; } } else /* (getheader == 0) */ { unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; unsigned long bwritten; if (outfile != INVALID_HANDLE_VALUE) { WriteFile(outfile,buffer.buffer,bytes,&bwritten,NULL); if (bwritten != bytes) { PrintMessage(_T("Error: write failed for %s"), fname); CloseHandle(outfile); DeleteFile(fname); cm_cleanup(cm); return -2; } } remaining -= bytes; if (remaining == 0) goto setTimeAndCloseFile; } } /* while(1) */ cm_cleanup(cm); return 0; }
int getlex () /* ввод лексемы */ { /* побочный эффект - заполнение lexval и lexsym */ register int c, i, radix = 10, neg = 0; if (backlexflag) { backlexflag = 0; return (lexlex); } loop: switch (c = getchar ()) { case EOF: return (0); case ';': while ((c = getchar ()) >= 0 && c!='\n') continue; case ' ': case '\t': case '\f': case '\n': case '\r': goto loop; case '"': lexlen = 0; while ((c = getchar ()) >= 0 && c!='"') { if (c == '\\') { c = getchar (); if (c < 0) break; switch (c) { case '\n': continue; case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'r': c = '\r'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c = getoct (c); break; } } lexsym[lexlen++] = c; } return (lexlex = TSTRING); case '#': c = getchar (); switch (c) { default: ungetc (c, stdin); return (lexlex = '#'); case '(': return (lexlex = TVECTOR); case '\\': lexval = getchr (); return (lexlex = TCHAR); case 't': case 'T': lexval = 1; return (lexlex = TBOOL); case 'f': case 'F': lexval = 0; return (lexlex = TBOOL); case 'b': case 'B': radix = 2; break; case 'o': case 'O': radix = 8; break; case 'd': case 'D': radix = 10; break; case 'x': case 'X': radix = 16; break; } c = getchar (); if (! isdigitx (c, radix) && c!='-' && c!='+' && c!='.') { ungetc (c, stdin); lexval = 0; return (lexlex = TINTEGER); } break; } if (c=='-' || c=='+') { lexsym[0] = c; c = getchar (); if (! isdigitx (c, radix)) { ungetc (c, stdin); c = lexsym[0]; goto lexsym; } neg = (lexsym[0] == '-'); } if (isdigitx (c, radix) || c=='.') { i = 0; while (i < MAXLEX-1 && c>=0 && isdigitx (c, radix)) { lexsym[i++] = c; c = getchar (); } if ((c=='.' || c=='E' || c=='e' || c=='S' || c=='s' || c=='F' || c=='f' || c=='D' || c=='d' || c=='L' || c=='l') && i<MAXLEX-1) { if (c=='.') { lexsym[i++] = c; c = getchar (); while (i < MAXLEX-1 && c>=0 && isdigitx (c, radix)) { lexsym[i++] = c; c = getchar (); } } if ((c=='E' || c=='e' || c=='S' || c=='s' || c=='F' || c=='f' || c=='D' || c=='d' || c=='L' || c=='l') && i<MAXLEX-1) { lexsym[i++] = c; c = getchar (); if ((c=='+' || c=='-') && i<MAXLEX-1) { lexsym[i++] = c; c = getchar (); } while (i < MAXLEX-1 && c>=0 && isdigitx (c, radix)) { lexsym[i++] = c; c = getchar (); } } if (c >= 0) ungetc (c, stdin); lexsym[i] = 0; lexrealval = strtodx (lexsym, 0, radix); if (neg) lexrealval = -lexrealval; return (lexlex = TREAL); } if (c >= 0) ungetc (c, stdin); lexsym[i] = 0; lexval = strtol (lexsym, 0, radix); if (neg) lexval = -lexval; return (lexlex = TINTEGER); } if (isletterx (c)) { lexsym: i = 0; while (i < MAXLEX-1) { lexsym[i++] = c; c = getchar (); if (c < 0) break; if (! isletterx (c)) { ungetc (c, stdin); break; } } if (i == 1 && lexsym[0] == '.') return (lexlex = '.'); lexsym[i] = 0; return (lexlex = TSYMBOL); } return (lexlex = c); }
/** * Unarchives the indicated tarred, gzipped, or gzipped tar file. * Each directory and file in the archive is created. * * \param prepend_path A string to be prepended to all output filenames. * * \return -1 on error, otherwise the number of files the archive contained. */ int ExpandTGZ(const char *archive_fname, const char *prepend_path) { gzFile in; union tar_buffer buffer; int len; int getheader = 1; int remaining = 0; FILE *outfile = NULL; char fname[BLOCKSIZE]; char fullname[1024]; time_t tartime; int files_encountered = 0; /* * Process the TGZ file */ in = gzopen(archive_fname, "rb"); if (in == NULL) { // fprintf(stderr,"%s: Couldn't gzopen %s\n", prog, TGZfile); return -1; } while (1) { len = gzread(in, &buffer, BLOCKSIZE); if (len < 0) { // error (gzerror(in, &err)); return -1; } /* * Always expect complete blocks to process * the tar information. */ if (len != BLOCKSIZE) { // error("gzread: incomplete block read"); gzclose(in); return -1; } /* * If we have to get a tar header */ if (getheader == 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ if ((len == 0) || (buffer.header.name[0]== 0)) break; tartime = (time_t)getoct(buffer.header.mtime, 12); strncpy(fname, buffer.header.name, BLOCKSIZE); strcpy(fullname, prepend_path); strcat(fullname, fname); switch (buffer.header.typeflag) { case DIRTYPE: vtCreateDir(fullname); break; case REGTYPE: case AREGTYPE: remaining = getoct(buffer.header.size, 12); if (remaining) { outfile = vtFileOpen(fullname,"wb"); if (outfile == NULL) { /* try creating directory */ char *p = strrchr(fullname, '/'); if (p != NULL) { *p = '\0'; vtCreateDir(fullname); *p = '/'; outfile = vtFileOpen(fullname,"wb"); } } // fprintf(stderr, "%s %s\n", (outfile) ? "Extracting" : "Couldn't create", fname); files_encountered++; } else outfile = NULL; /* * could have no contents */ getheader = (remaining) ? 0 : 1; break; default: break; } } else { uint bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; if (outfile != NULL) { if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) { // fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname); fclose(outfile); unlink(fname); } } remaining -= bytes; if (remaining == 0) { getheader = 1; if (outfile != NULL) { #ifdef WIN32 fclose(outfile); outfile = NULL; #else struct utimbuf settime; settime.actime = settime.modtime = tartime; fclose(outfile); outfile = NULL; utime(fname,&settime); #endif } } } } if (gzclose(in) != Z_OK) { // error("failed gzclose"); return -1; } return files_encountered; }