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

📄 filetype.c

📁 zlib压缩原码
💻 C
字号:
/* * filetype.c * * Copyright (C) 1993 Alain Knaff */#define _LARGEFILE64_SOURCE#define _GNU_SOURCE#include "sysincludes.h"static int is_initialised=0;static FilenameActions *filenameActions;static char *default_uncompressor[]= { UNCOMPR, 0 };#ifndef SECURITYstatic char *custom_uncompressor[]= { 0, 0 };#endifchar *zlib_ext;int zlib_extlen;int zlib_mode;char *zlib_tmp;char **zlib_uncompressor;#define ENV_PREFIX "LD_ZLIB_"/** * Remove LD_PRELOAD=uncompress.o from environment in case CM_DISAB_CHILDREN * is set * We cannot use putenv or setenv here, because they work on a copy of the * environment, which will be overwritten between the time this _init is * called, and main is called */static void remove_ld_preload() {  if(zlib_mode & CM_DISAB_CHILD) {    char preload_name[]="LD_PRELOAD=";    char *uncompr = "/uncompress.o";          int i;    for(i=0; environ[i]; i++) {      if(!strncmp(environ[i], preload_name, sizeof(preload_name)-1)) {	/* strip out all items contains "uncompress.o" from LD_PRELOAD var */	char *rptr = environ[i] + sizeof(preload_name) - 1;	char *lastbegin=rptr;	char *wptr = rptr;	int comp=1;	int atbegin=1;	lastbegin = wptr;	while(1) {	  if(*rptr == ':') {	    if(uncompr[comp] == '\0') {	      wptr = lastbegin;	      if(atbegin) {		rptr++;		comp=1;		continue;	      }	    }	    comp = 1;	    lastbegin = wptr;	    atbegin=0;	  } else if(*rptr == '\0') {	    if(uncompr[comp] == '\0') {	      wptr = lastbegin;	    }	    *wptr='\0';	    break;	    	  } else if(*rptr == uncompr[comp]) {	    comp++;	  } else {	    comp=0;	  }	  *wptr++=*rptr++;	 	}	      }    }  }}static char *mode_table[] = {  "DISABLE",  "READDIR_COMPR",  "VERBOSE",  "UNLINK",  "NOCONF"};void zlib_initialise(void){  int modemask;  int olderrno;#ifndef SECURITY  int i;  char env_buffer[1024];  char *value;#endif  olderrno = errno;  if ( !is_initialised ){    CommandActions *cma;#ifdef HAVE_PROC    char cmdline[1025];    int fd,n;#else    char *cmdline;#endif    char *progname=0;    zlib_mode = modemask = 0;    zlib_ext = EXT;    zlib_extlen = strlen(zlib_ext);    zlib_uncompressor = default_uncompressor;    zlib_tmp = TMP;#ifndef SECURITY    if (getuid() == geteuid() || getgid() == getegid()){      zlib_tmp = getenv("LD_ZLIB_TMP");      if ( zlib_tmp == 0 )	zlib_tmp = TMP;            zlib_ext= getenv("LD_ZLIB_EXT");      if ( zlib_ext == 0 )	zlib_ext = EXT;      zlib_extlen = strlen(zlib_ext);      if ( zlib_extlen > MAXEXTLEN ){	fprintf(stderr,"extension too long, taking default\n");	zlib_ext = EXT;      }      custom_uncompressor[0] = getenv("LD_ZLIB_UNCOMPRESSOR");      if ( custom_uncompressor[0] ){	zlib_uncompressor = custom_uncompressor;      } else	zlib_uncompressor = default_uncompressor;            strcpy(env_buffer, ENV_PREFIX);      for ( i=0; i< ( sizeof(mode_table) / sizeof(char *) ); i++){	strcpy( env_buffer+(sizeof( ENV_PREFIX ) - 1 ), mode_table[i] );	if ( (value=getenv ( env_buffer )) ){	  if ( ( strcmp( value, "on" ) == 0 ) || ( strcmp( value, "1" ) == 0 )){	    zlib_mode |= ( 1 << ( i + 1 ));	  }else 	    if ( ( strcmp( value, "off" ) ) && ( strcmp( value, "0" ) ))	      continue;	  modemask |= ( 1 << ( i + 1 ));	  	}      }      if ( zlib_mode & CM_DISAB){	is_initialised = 2;	errno = olderrno;	return;      }    }#endif#ifdef HAVE_PROC    /* get command line */        strcpy(cmdline, "unknown");    fd=syscall(SYS_open,"/proc/self/cmdline", O_RDONLY);    if ( fd > 0 ){      cmdline[1024]='\0';      n = read( fd, cmdline,1024 );      if ( n < 1 )	cmdline[0] = '\0';      else	cmdline[n] = '\0';      close(fd);    }#else    /* where does the command line live on a sun ? */    /* horrible undocumented kludge... This might even work on a proc-less      * linux*/    do {      extern char **environ;      int zerosfound;      if ( environ == 0 ){	cmdline="";	break;      }      cmdline = *environ;      if ( cmdline == 0 ){	cmdline="";	break;      }      zerosfound = 0;      while(zerosfound < 2 ){	cmdline--;	if ( *cmdline == 0 )	  zerosfound++;	else	  zerosfound = 0;      }      cmdline +=2;    } while(0);#endif    progname = strrchr(cmdline, '/' );    if ( !progname )      progname = cmdline;    else      progname++;    if ( zlib_mode & CM_VERBOSE)      fprintf(stderr,"progname = %s\n",progname);    is_initialised = 1;    /* get user configuration */#ifndef NO_RT_CONF    if ( ! ( zlib_mode & CM_NORTCONF ) )      zlib_getuserconf(progname, &filenameActions, &zlib_mode, &modemask);#endif    if ( modemask != CM_ALL_MODES ){      /* if we couldn't get the user configuration, use compiled in defaults */      cma = zlib_commandActions;      while ( cma->name && strcmp(cma->name, progname ) )	cma++;      if ( ( modemask & CM_HAVE_FA ) == 0 )	filenameActions = cma->actions;      zlib_mode |= ( cma->cm_type & ~modemask);    }    remove_ld_preload();    is_initialised = 2;    /* initialisation completely done */  }   errno = olderrno;}#ifdef __ELF__#ifdef RTLD_NEXTint (*zlib_real_access)(const char *, int);int (*zlib_real_chmod) (const char *, mode_t);int (*zlib_real_chown) (const char *, uid_t, gid_t);int (*zlib_real_getdents) (unsigned int, struct dirent *, unsigned int);int (*zlib_real_link) (const char *, const char *);int (*zlib_real_open) (const char *, int, mode_t);struct dirent *(*zlib_real_readdir) (DIR *);struct dirent64 *(*zlib_real_readdir64) (DIR *);int (*zlib_real_readlink) (const char *, char *, size_t);int (*zlib_real_rename) (const char *, const char *);# ifdef HAVE___XSTATint (*zlib_real_xstat) (int vers, const char *, struct stat *);int (*zlib_real_fxstat) (int vers, int fd, struct stat *);int (*zlib_real_lxstat) (int vers, const char *, struct stat *);# elseint (*zlib_real_stat) (const char *, struct stat *);int (*zlib_real_lstat) (const char *, struct STAT32 *);# endif# ifdef HAVE___XSTAT64int (*zlib_real_xstat64) (int vers, const char *, struct stat64 *);int (*zlib_real_lxstat64) (int vers, const char *, struct stat64 *);# elif defined HAVE_STAT64int (*zlib_real_stat64) (const char *, struct stat64 *);int (*zlib_real_lstat64) (const char *, struct stat64 *);# endifint (*zlib_real_symlink) (const char *, const char *);int (*zlib_real_unlink) (const char *);int (*zlib_real_utime) (const char *, struct utimbuf *);int (*zlib_real_utimes) (const char *, struct timeval *);#endifstatic int _is_rtld_initialized = 0;void _init(void){    if(_is_rtld_initialized) {	return;    }    _is_rtld_initialized=1;#ifdef RTLD_NEXT  zlib_real_access = dlsym(RTLD_NEXT, "access");  zlib_real_chmod = dlsym(RTLD_NEXT, "chmod");  zlib_real_chown = dlsym(RTLD_NEXT, "chown");  zlib_real_getdents = dlsym(RTLD_NEXT, "getdents");  zlib_real_link = dlsym(RTLD_NEXT, "link");# ifdef HAVE___LIBC_OPEN  zlib_real_open = dlsym(RTLD_NEXT, "__libc_open");# else  zlib_real_open = dlsym(RTLD_NEXT, "open");# endif  zlib_real_readdir = dlsym(RTLD_NEXT, "readdir");  zlib_real_readdir64 = dlsym(RTLD_NEXT, "readdir64");  zlib_real_readlink = dlsym(RTLD_NEXT, "readlink");  zlib_real_rename = dlsym(RTLD_NEXT, "rename");  zlib_real_symlink = dlsym(RTLD_NEXT, "symlink");  zlib_real_unlink = dlsym(RTLD_NEXT, "unlink");  zlib_real_utime = dlsym(RTLD_NEXT, "utime");  zlib_real_utimes = dlsym(RTLD_NEXT, "utimes");# ifdef HAVE___XSTAT  zlib_real_xstat = dlsym(RTLD_NEXT, "__xstat");  zlib_real_fxstat = dlsym(RTLD_NEXT, "__fxstat");  zlib_real_lxstat = dlsym(RTLD_NEXT, "__lxstat");# else  zlib_real_stat = dlsym(RTLD_NEXT, "stat");  zlib_real_lstat = dlsym(RTLD_NEXT, "lstat");# endif# ifdef HAVE___XSTAT64  zlib_real_xstat64 = dlsym(RTLD_NEXT, "__xstat64");  zlib_real_lxstat64 = dlsym(RTLD_NEXT, "__lxstat64");# elif defined HAVE_STAT64  zlib_real_stat64 = dlsym(RTLD_NEXT, "stat64");  zlib_real_lstat64 = dlsym(RTLD_NEXT, "lstat64");# endif#endif  zlib_initialise();}#endifstatic int masks[]= { 	PM_READ_MASK,	PM_CREATE_MASK,	PM_APPEND_MASK,	PM_UNCOMPR_MASK,	PM_SIZE_COMPR_MASK};#define	NUMBER(x)	(sizeof(x) / sizeof(*(x)))static void quick_stat(__const char *name, dev_t *dev, ino_t *ino){  int olderrno;  int st;  struct STAT32 buf;  olderrno = errno;  st = ___zlibc_stat(name, &buf );  errno = olderrno;  if ( st < 0 ) {    /* file not found */    *ino = 0;    *dev = 0;  } else {    *dev = buf.st_dev;    *ino = buf.st_ino;  }}static void initialize_fa(FilenameActions *fa){  if(fa->is_initialized)    return;  fa->is_initialized = 1;  quick_stat(fa->name, &fa->dev, &fa->ino);}static int check_subdir(__const char *name, int dirlength,			int fd, FilenameActions *fa, int subdir){  char dirname[MAXPATHLEN+1];  struct stat buf;  dev_t last_dev=0;  ino_t last_ino=0;  int cwd;  int cfd;  int closefd=0; /* fd must be closed on exit */  int r;  initialize_fa(fa);  if(!fa->ino)    return 0;  if(fd == -1){    if(dirlength - 1 > MAXPATHLEN)      return 0;    if(!dirlength)      strcpy(dirname,".");    else      strncpy(dirname,name, dirlength-1);    closefd = fd = zlib_real_open(dirname, O_RDONLY, 0);    if(fd < 0)      return 0;  }  cwd = -1;  cfd = fd;  while(1) {      fstat(cfd, &buf);    if(cwd >= 0)      close(cfd);    if(buf.st_dev == fa->dev &&       buf.st_ino == fa->ino) {      r = 1;      break;    }    if(!subdir) {      r = 0;      break;    }    if(cwd >= 0 &&       buf.st_dev == last_dev &&       buf.st_ino == last_ino) {            /* root reached */      r = 0;      break;    }    last_dev = buf.st_dev;    last_ino = buf.st_ino;#ifdef HAVE_FCHDIR    if(cwd < 0) {      /* remember old directory */      cwd = zlib_real_open(".", O_RDONLY, 0);      if(cwd < 0) {	r = 0;	break;      }      fchdir(fd);  /* go to the new directory */    }    chdir(".."); /* move up one level */    cfd = zlib_real_open(".", O_RDONLY, 0);    if(cfd < 0) {      r = 0;      break;    }#else    if(fd != -1) {      /* unknown filename */      r = 0;      break;    }    if(strlen(dirname) > MAXPATHLEN - 3) {      r = 0; /* filename too long */      break;    }    strcat(dirname, "/..");    cfd = zlib_real_open(dirname, O_RDONLY, 0);    if(cfd < 0) {      r = 0;      break;    }#endif  }#ifdef HAVE_FCHDIR  if(cwd != -1) {    /* revert back to real current directory */    fchdir(cwd);    close(cwd);  }#endif  if(closefd)    close(fd);  return r;}int zlib_getfiletype(__const char *name, int fd){  __const char *basename;  FilenameActions *fa;  int length;  int dirlength;  int basenamelength;  int pipe_mode;  int i;  int match;  int dostop;  int dev;  struct STAT32 buf;  int olderrno;  int st;  /* preprocessing */  dev=-1;  basename = strrchr( name, '/' );  if ( !basename )    basename = name;  else    basename++;    dirlength = basename - name;  basenamelength = strlen(basename);  length = dirlength + basenamelength;  zlib_initialise();  if ( is_initialised == 1 )    /* transition period, loading user supplied defaults */    return PM_SHOW_PIPE;  fa = filenameActions;  pipe_mode=0;  while ( 1 ){    match=0;    switch( fa->fa_type ){      /* before calling strncmp, the length are compared in order to speed up       * the search. In most cases, the length doesn't match, this way we don't       * need a costly call to strncmp */    case FA_ALL:    case FA_ALL2:      match=1;      break;    case FA_DIR:      if(fd == -1 && name[0] == '/')	match= fa->namelength == dirlength &&	  !strncmp(fa->name, name, dirlength);      else	match = check_subdir(name, dirlength, fd, fa, 0);      break;    case FA_SUBDIR:      if(fd == -1 && name[0] == '/')		match= fa->namelength<=dirlength &&	  !strncmp(fa->name,name,fa->namelength);      else	match = check_subdir(name, dirlength, fd, fa, 1);      break;    case FA_BASENAME:      match= fa->namelength == basenamelength && !strcmp(fa->name, basename);      break;    case FA_FILENAME:      match= fa->namelength == length && !strcmp(fa->name, name);      break;    case FA_SUFFIX:      match= fa->namelength <= basenamelength &&	      !strcmp(fa->name, basename + (basenamelength - fa->namelength));      break;    case FA_FS:      if ( dev == -1 ){	olderrno = errno;	if ( fd != -1 )	  st = fSTAT32(fd,&buf );	else {	  char namez[MAXPATHLEN + MAXEXTLEN + 1];	  strncpy(namez, name, MAXPATHLEN);	  strncat(namez, zlib_ext, MAXPATHLEN);	  st = ___zlibc_stat(namez, &buf );	}	errno = olderrno;	if ( st < 0 )	  dev = 0;	else	  dev = buf.st_dev;      }      match = buf.st_dev == fa->namelength;      break;    default:      fprintf(stderr,"Error in filenameActions %x in %d\n", fa->fa_type, 	      (int) getpid());      sleep(3);      return 0;      break;    }    if (match){      dostop=1;      for (i=0; i< NUMBER(masks); i++){	if (!(pipe_mode & masks[i]))	  pipe_mode |= fa->pipe_mode & masks[i];	if (!(pipe_mode & masks[i]))	  dostop=0;      }      if ( dostop || fa->fa_type == FA_ALL){#ifdef DEBUG	fprintf(stderr,"pm=%x\n", pipe_mode);#endif	return pipe_mode;      }    }    fa++;  }}

⌨️ 快捷键说明

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