⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 untgz.c

📁 this gcc-g++-3.3.1.tar.gz is a source file of gcc, you can learn more about gcc through this codes f
💻 C
字号:
/* * untgz.c -- Display contents and/or extract file from * a gzip'd TAR file * written by "Pedro A. Aranda Guti\irrez" <paag@tid.es> * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org> */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <errno.h>#include <fcntl.h>#ifdef unix# include <unistd.h>#else# include <direct.h># include <io.h>#endif#include "zlib.h"#ifdef WIN32#  ifndef F_OK#    define F_OK (0)#  endif#  ifdef _MSC_VER#    define mkdir(dirname,mode) _mkdir(dirname)#    define strdup(str)         _strdup(str)#    define unlink(fn)          _unlink(fn)#    define access(path,mode)   _access(path,mode)#  else#    define mkdir(dirname,mode) _mkdir(dirname)#  endif#else#  include <utime.h>#endif/* Values used in typeflag field.  */#define REGTYPE	 '0'		/* regular file */#define AREGTYPE '\0'		/* regular file */#define LNKTYPE  '1'		/* link */#define SYMTYPE  '2'		/* reserved */#define CHRTYPE  '3'		/* character special */#define BLKTYPE  '4'		/* block special */#define DIRTYPE  '5'		/* directory */#define FIFOTYPE '6'		/* FIFO special */#define CONTTYPE '7'		/* reserved */#define BLOCKSIZE 512struct tar_header{				/* byte offset */  char name[100];		/*   0 */  char mode[8];			/* 100 */  char uid[8];			/* 108 */  char gid[8];			/* 116 */  char size[12];		/* 124 */  char mtime[12];		/* 136 */  char chksum[8];		/* 148 */  char typeflag;		/* 156 */  char linkname[100];		/* 157 */  char magic[6];		/* 257 */  char version[2];		/* 263 */  char uname[32];		/* 265 */  char gname[32];		/* 297 */  char devmajor[8];		/* 329 */  char devminor[8];		/* 337 */  char prefix[155];		/* 345 */				/* 500 */};union tar_buffer {  char               buffer[BLOCKSIZE];  struct tar_header  header;};enum { TGZ_EXTRACT = 0, TGZ_LIST };static char *TGZfname	OF((const char *));void TGZnotfound	OF((const char *));int getoct		OF((char *, int));char *strtime		OF((time_t *));int ExprMatch		OF((char *,char *));int makedir		OF((char *));int matchname		OF((int,int,char **,char *));void error		OF((const char *));int  tar		OF((gzFile, int, int, int, char **));void help		OF((int));int main		OF((int, char **));char *prog;/* This will give a benign warning */static char *TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL };/* Return the real name of the TGZ archive *//* or NULL if it does not exist. */static char *TGZfname OF((const char *fname)){  static char buffer[1024];  int origlen,i;    strcpy(buffer,fname);  origlen = strlen(buffer);  for (i=0; TGZprefix[i]; i++)    {       strcpy(buffer+origlen,TGZprefix[i]);       if (access(buffer,F_OK) == 0)         return buffer;    }  return NULL;}/* error message for the filename */void TGZnotfound OF((const char *fname)){  int i;  fprintf(stderr,"%s : couldn't find ",prog);  for (i=0;TGZprefix[i];i++)    fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n",            fname,            TGZprefix[i]);  exit(1);}/* help functions */int getoct(char *p,int width){  int result = 0;  char c;    while (width --)    {      c = *p++;      if (c == ' ')	continue;      if (c == 0)	break;      result = result * 8 + (c - '0');    }  return result;}char *strtime (time_t *t){  struct tm   *local;  static char result[32];  local = localtime(t);  sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d",	  local->tm_mday, local->tm_mon+1, local->tm_year+1900,	  local->tm_hour, local->tm_min,   local->tm_sec);  return result;}/* regular expression matching */#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))int ExprMatch(char *string,char *expr){  while (1)    {      if (ISSPECIAL(*expr))	{	  if (*expr == '/')	    {	      if (*string != '\\' && *string != '/')		return 0;	      string ++; expr++;	    }	  else if (*expr == '*')	    {	      if (*expr ++ == 0)		return 1;	      while (*++string != *expr)		if (*string == 0)		  return 0;	    }	}      else	{	  if (*string != *expr)	    return 0;	  if (*expr++ == 0)	    return 1;	  string++;	}    }}/* recursive make directory *//* abort if you get an ENOENT errno somewhere in the middle *//* e.g. ignore error "mkdir on existing directory" *//* *//* return 1 if OK *//*        0 on error */int makedir (char *newdir){  char *buffer = strdup(newdir);  char *p;  int  len = strlen(buffer);    if (len <= 0) {    free(buffer);    return 0;  }  if (buffer[len-1] == '/') {    buffer[len-1] = '\0';  }  if (mkdir(buffer, 0775) == 0)    {      free(buffer);      return 1;    }  p = buffer+1;  while (1)    {      char hold;            while(*p && *p != '\\' && *p != '/')	p++;      hold = *p;      *p = 0;      if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT))	{	  fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer);	  free(buffer);	  return 0;	}      if (hold == 0)	break;      *p++ = hold;    }  free(buffer);  return 1;}int matchname (int arg,int argc,char **argv,char *fname){  if (arg == argc)		/* no arguments given (untgz tgzarchive) */    return 1;  while (arg < argc)    if (ExprMatch(fname,argv[arg++]))      return 1;  return 0; /* ignore this for the moment being */}/* Tar file list or extract */int tar (gzFile in,int action,int arg,int argc,char **argv){  union  tar_buffer buffer;  int    len;  int    err;  int    getheader = 1;  int    remaining = 0;  FILE   *outfile = NULL;  char   fname[BLOCKSIZE];  time_t tartime;    if (action == TGZ_LIST)    printf("     day      time     size                       file\n"	   " ---------- -------- --------- -------------------------------------\n");  while (1)    {      len = gzread(in, &buffer, BLOCKSIZE);      if (len < 0)	error (gzerror(in, &err));      /*       * Always expect complete blocks to process       * the tar information.       */      if (len != BLOCKSIZE)	error("gzread: incomplete block read");            /*       * 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);	  strcpy(fname,buffer.header.name);	  	  switch (buffer.header.typeflag)	    {	    case DIRTYPE:	      if (action == TGZ_LIST)		printf(" %s     <dir> %s\n",strtime(&tartime),fname);	      if (action == TGZ_EXTRACT)		makedir(fname);	      break;	    case REGTYPE:	    case AREGTYPE:	      remaining = getoct(buffer.header.size,12);	      if (action == TGZ_LIST)		printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);	      if (action == TGZ_EXTRACT)		{		  if ((remaining) && (matchname(arg,argc,argv,fname)))		    {		      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");			}		      }		      fprintf(stderr,			      "%s %s\n",			      (outfile) ? "Extracting" : "Couldn't create",			      fname);		    }		  else		    outfile = NULL;		}	      /*	       * could have no contents	       */	      getheader = (remaining) ? 0 : 1;	      break;	    default:	      if (action == TGZ_LIST)		printf(" %s     <---> %s\n",strtime(&tartime),fname);	      break;	    }	}      else	{	  unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;	  if ((action == TGZ_EXTRACT) && (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 ((action == TGZ_EXTRACT) && (outfile != NULL))		{#ifdef WIN32		  HANDLE hFile;		  FILETIME ftm,ftLocal;		  SYSTEMTIME st;		  struct tm localt; 		  fclose(outfile);		  localt = *localtime(&tartime);		  hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE,				     0, NULL, OPEN_EXISTING, 0, NULL);		  		  st.wYear = (WORD)localt.tm_year+1900;		  st.wMonth = (WORD)localt.tm_mon;		  st.wDayOfWeek = (WORD)localt.tm_wday;		  st.wDay = (WORD)localt.tm_mday;		  st.wHour = (WORD)localt.tm_hour;		  st.wMinute = (WORD)localt.tm_min;		  st.wSecond = (WORD)localt.tm_sec;		  st.wMilliseconds = 0;		  SystemTimeToFileTime(&st,&ftLocal);		  LocalFileTimeToFileTime(&ftLocal,&ftm);		  SetFileTime(hFile,&ftm,NULL,&ftm);		  CloseHandle(hFile);		  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 0;}/* =========================================================== */void help(int exitval){  fprintf(stderr,	  "untgz v 0.1\n"	  " an sample application of zlib 1.0.4\n\n"          "Usage : untgz TGZfile            to extract all files\n"          "        untgz TGZfile fname ...  to extract selected files\n"          "        untgz -l TGZfile         to list archive contents\n"          "        untgz -h                 to display this help\n\n");  exit(exitval);}void error(const char *msg){    fprintf(stderr, "%s: %s\n", prog, msg);    exit(1);}/* ====================================================================== */int _CRT_glob = 0;	/* disable globbing of the arguments */int main(int argc,char **argv){    int 	action = TGZ_EXTRACT;    int 	arg = 1;    char	*TGZfile;    gzFile	*f;        prog = strrchr(argv[0],'\\');    if (prog == NULL)      {	prog = strrchr(argv[0],'/');	if (prog == NULL)	  {	    prog = strrchr(argv[0],':');	    if (prog == NULL)	      prog = argv[0];	    else	      prog++;	  }	else	  prog++;      }    else      prog++;        if (argc == 1)      help(0);    if (strcmp(argv[arg],"-l") == 0)      {	action = TGZ_LIST;	if (argc == ++arg)	  help(0);      }    else if (strcmp(argv[arg],"-h") == 0)      {	help(0);      }    if ((TGZfile = TGZfname(argv[arg])) == NULL)      TGZnotfound(argv[arg]);                ++arg;    if ((action == TGZ_LIST) && (arg != argc))      help(1);/* *  Process the TGZ file */    switch(action)      {      case TGZ_LIST:      case TGZ_EXTRACT:	f = gzopen(TGZfile,"rb");	if (f == NULL)	  {	    fprintf(stderr,"%s: Couldn't gzopen %s\n",		    prog,		    TGZfile);	    return 1;	  }	exit(tar(f, action, arg, argc, argv));      break;	      default:	error("Unknown option!");	exit(1);      }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -