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

📄 sysutils.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 3 页
字号:
Int32get_fs_status(  UChar		*path,  Int32		*blocksize,  Real64	*bsize,  Real64	*bfree,  Real64	*bavail){#ifndef	HAVE_STATVFS  struct statfs	statfsb;#else  struct statvfs	statfsb;#endif#ifdef	HAVE_STATVFS		/* sees to be well-defined */	  if(statvfs(path, &statfsb) == -1)#else#if defined(_AIX) || defined(linux) || defined(__hpux) || defined(hpux) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)	  if(statfs(path, &statfsb) == -1)#else#if defined(sun)	  if(statfs(path, &statfsb, sizeof(statfsb), 0) == -1)#else#if defined(sgi)	  if(statfs(path, &statfsb, sizeof(statfsb), 0) == -1)#else#if defined(__osf__)	  if(statfs(path, &statfsb, sizeof(statfsb)) == -1)#else#if defined(UnixWare_5)	  if(statfs(path, &statfsb) == -1)#else#error	undefined architecture#endif#endif#endif#endif#endif#endif	    return(-1);  if(bavail)#if	defined(HAVE_STRUCT_STAT_BAVAIL) || defined(HAVE_STATVFS)	*bavail = (Real64) statfsb.f_bavail;#else	*bavail = (Real64) statfsb.f_bfree;#endif  if(bfree)	*bfree = (Real64) statfsb.f_bfree;  if(bsize)	*bsize = (Real64) statfsb.f_blocks;  if(blocksize)#ifndef	HAVE_STATVFS	*blocksize = (Int32) statfsb.f_bsize;#else	*blocksize = (Int32) statfsb.f_frsize;#endif  return(0);}#else	/* defined(_WIN32) */Int32get_fs_space(UChar * path, Real64 * size){  if(size)    *size = 10000000.0;  return(0);}#endif	/* ifelse defined(_WIN32) */static intset_eff_ugids1(uid_t uid, gid_t gid, int ngids, gid_t * gids, Flag ignerr){  int		r = 0, ncgids = 0;  uid_t		ceuid;  gid_t		cegid, *cgids = NULL;  ceuid = geteuid();  cegid = getegid();  if((ngids > 0 && gids) || (gid != (gid_t) -1)){    if(ceuid){#ifdef	HAVE_SETEUID	/* if that works, we can force group setting */	seteuid(0);#else#ifdef	HAVE_SETREUID	setreuid(-1, 0);#else#ifdef	HAVE_SETRESUID	setresuid(-1, 0, -1);#else#error	No function to set the effective user id#endif#endif#endif	if(!(geteuid())){	  if(uid == (uid_t) -1)	    uid = ceuid;		/* to really go back later */	  ceuid = 0;	}    }  }  if(ngids > 0 && gids){    if(get_groups(&ncgids, &cgids) && !ignerr)	GETOUTR(-1);    r = setgroups(ngids, gids);    if(r && !ignerr)	GETOUTR(r);  }  if(gid != (gid_t) -1 && gid != cegid){    r =#ifdef	HAVE_SETEGID	setegid(gid);#else#ifdef	HAVE_SETREGID	setregid(-1, gid);#else#ifdef	HAVE_SETRESGID	setresgid(-1, gid, -1);#else#error	No function to set the effective group id#endif#endif#endif    if(r && !ignerr)	GETOUTR(r);  }  if(uid != (uid_t) -1 && uid != ceuid){    r =#ifdef	HAVE_SETEUID	seteuid(uid);#else#ifdef	HAVE_SETREUID	setreuid(-1, uid);#else#ifdef	HAVE_SETRESUID	setresuid(-1, uid, -1);#else#error	No function to set the effective user id#endif#endif#endif    if(r && !ignerr)	GETOUTR(r);  } cleanup:  ZFREE(cgids);  return(r); getout:  set_eff_ugids1(ceuid, cegid, ncgids, cgids, YES);  CLEANUP;}intset_eff_ugids(uid_t uid, gid_t gid, int ngids, gid_t * gids){  return(set_eff_ugids1(uid, gid, ngids, gids, NO));}intget_groups(int * ngids, gid_t ** gids){  int		ngs;  gid_t		*gs, g;  ngs = getgroups(0, &g);  if(!gids){    if(ngids)	*ngids = ngs;    return(0);  }  gs = NEWP(gid_t, ngs);  if(!gs)    return(-1);  getgroups(ngs, gs);  *gids = gs;  if(ngids)    *ngids = ngs;  return(0);}static Int32cmp_mnt_by_devno(void * ptr1, void * ptr2){  dev_t		d1, d2;  d1 = ((MntEnt *) ptr1)->dev;  d2 = ((MntEnt *) ptr2)->dev;  return(d1 > d2 ? 1 : (d1 < d2 ? -1 : 0));}UChar *mount_tab_file(){#if	defined(linux) || defined(sgi) || ( defined(sun) && ! defined(HAVE_GETMNTENT_TWO_ARGS) )#define	MTABFILE	"/etc/mtab"#else#if	defined(sun) || defined(__hpux) || defined(hpux) || defined(UnixWare_5)#define	MTABFILE	"/etc/mnttab"#else#if	defined(__osf__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_AIX)#define	MTABFILE	NULL#endif#endif#endif  return(MTABFILE);}#ifndef	HAVE_ENDMNTENT#define	endmntent	fclose#endif#ifndef	HAVE_SETMNTENT#define	setmntent	fopen#endifMntEnt *get_all_mounts(Int32 * num_mounts){  Int32		nmnt = 0, n, l, i;  UChar		*dir, *typestr, *devstr, *cptr;  MntEnt	*mnts = NULL;  FILE		*mtabfp = NULL;  struct stat	statb;#ifdef	HAVE_GETMNTENT#ifndef	HAVE_GETMNTENT_TWO_ARGS  struct mntent	*mntentptr;#else  struct mnttab	mntent;#endif#endif#ifdef	HAVE_GETFSSTAT  struct statfs	*statfsptr, *statfsbuf = NULL;#endif  UChar		*mntentbuf = NULL, **vfslines = NULL;  int		i1;  Int32		nvfslines = 0, nmntent;		/* this stuff is for AIX */#ifdef	HAVE_GETMNTENT  mtabfp = setmntent(MTABFILE, "r");  if(!mtabfp)    return(NULL);#else	/* defined(HAVE_GETMNTENT) */#ifdef	HAVE_MNTCTL			/* the AIX stuff */  n = 8;		/* die schie遝n echt den Vogel ab */  forever{    mntentbuf = ZRENEWP(mntentbuf, UChar, n);    if(!mntentbuf)	GETOUT;    nmntent = mntctl(MCTL_QUERY, n, mntentbuf);    if(nmntent < 0)	GETOUT;    if(nmntent == 0){	n = *((size_t *) &(mntentbuf[0]));	continue;    }    break;  }  vfslines = read_asc_file("/etc/vfs", &nvfslines);  if(!vfslines)    GETOUT;  for(i = 0; i < nvfslines; i++){    massage_string(vfslines[i]);    if( (cptr = first_space(vfslines[i])) )	*cptr = '\0';  }#else#ifdef	HAVE_GETFSSTAT  n = getfsstat(NULL, 0, MNT_NOWAIT);  statfsbuf = NEWP(struct statfs, n);  if(!statfsbuf)    GETOUT;  mntentbuf = (UChar *) statfsbuf;	/* for free below */  if((nmntent = getfsstat(statfsbuf, n * sizeof(struct statfs), MNT_NOWAIT)) < 0)    GETOUT;#else#error	No way to get the (status of the) mounted filesystems#endif#endif#endif#ifdef	HAVE_GETMNTENT#ifndef	HAVE_GETMNTENT_TWO_ARGS  while( (mntentptr = getmntent(mtabfp)) ){    dir = mntentptr->mnt_dir;#else  while(!getmntent(mtabfp, &mntent)){    dir = mntent.mnt_mountp;#endif#else	/* defined(HAVE_GETMNTENT) */#ifdef	HAVE_MNTCTL  for(n = 0, cptr = mntentbuf; n < nmntent;		cptr += ((struct vmount *) cptr)->vmt_length, n++){    devstr = cptr + sizeof(struct vmount);    dir = devstr + align_n(strlen(devstr) + 1, 32 / 8);#else#ifdef	HAVE_GETFSSTAT  for(n = 0, statfsptr = statfsbuf; n < nmntent; n++, statfsptr++){    dir = statfsptr->f_mntonname;#endif#endif#endif    if(lstat(dir, &statb) < 0)	continue;		/* can't read this -> leave out */#ifdef	HAVE_GETMNTENT#ifndef	HAVE_GETMNTENT_TWO_ARGS    typestr = mntentptr->mnt_type;    devstr = mntentptr->mnt_fsname;#else    typestr = mntent.mnt_fstype;    devstr = mntent.mnt_special;#endif#else	/* defined(HAVE_GETMNTENT) */#ifdef	HAVE_MNTCTL		/* on AIX we must search in /etc/vfs */    for(i = 0; i < nvfslines; i++){	if(vfslines[i][0] == '#' || vfslines[i][0] == '%' || !vfslines[i][0])	  continue;	l = strlen(vfslines[i]);	if(sscanf(vfslines[i] + l + 1, "%d", &i1) < 1)	  continue;	if(((struct vmount *) cptr)->vmt_gfstype == i1){	  typestr = vfslines[i];	  break;	}    }    if(i >= nvfslines)	continue;#else#ifdef	HAVE_GETFSSTAT    devstr = statfsptr->f_mntfromname;#ifdef	HAVE_MNT_NAMES    typestr = mnt_names[statfsptr->f_type];#else    typestr = statfsptr->f_fstypename;#endif#endif#endif#endif    mnts = ZRENEWP(mnts, MntEnt, nmnt + 2);    if(!mnts)	CLEANUP;    memset(mnts + nmnt, 0, sizeof(MntEnt) * 2);    mnts[nmnt].dev = statb.st_dev;    if(!(mnts[nmnt].dir = strdup(dir)))	GETOUT;    if(typestr)      if(!(mnts[nmnt].typestr = strdup(typestr)))	GETOUT;    if(devstr)      if(!(mnts[nmnt].devstr = strdup(devstr)))	GETOUT;    nmnt++;  }  if(num_mounts)    *num_mounts = nmnt;  q_sort(mnts, nmnt, sizeof(MntEnt), cmp_mnt_by_devno); cleanup:  if(mtabfp){    endmntent(mtabfp);  }  ZFREE(mntentbuf);  free_asc_file(vfslines, 0);  return(mnts); getout:  free_mounts(mnts);  CLEANUP;}static voidcry_out_loud_shit(UChar * msg, MntEnt * mnts, Int32 nmnts){  fprintf(stderr, ">>>>> Please, if someone reads this, send a mail to af@muc.de\n"		">>>>> containing the following output:\n");  fprintf(stderr, ">>>>> %s\n", msg);  while(nmnts > 0){    fprintf(stderr, ">>>>> `%s' `%s' `%s' %ld\n",		mnts->dir ? mnts->dir : (UChar *) "??",		mnts->typestr ? mnts->typestr : (UChar *) "??",		mnts->devstr ? mnts->devstr : (UChar *) "??",		(long int) mnts->dev);    mnts++;    nmnts--;  }}MntEnt *find_mnt_by_devno_dir(MntEnt * mounts, Int32 nmnt, dev_t devno, UChar * dnam){  MntEnt	cmpent, *mntptr;  Int32		first, last, found, i, n, l;  struct stat	statb;  if(dnam)    dnam = resolve_path__(dnam, NULL);  if(nmnt < 1)    for(nmnt = 0, mntptr = mounts; mntptr->dir; nmnt++, mntptr++);  cmpent.dev = devno;  mntptr = b_search(&cmpent, mounts, nmnt, sizeof(MntEnt), cmp_mnt_by_devno);  if(mntptr){    found = first = last = mntptr - mounts;	/* there can be several with */    while(first > 0){				/* the same device number */	if(mounts[first - 1].dev != devno)	/* when there are loopback */	  break;				/* mounts. We have to find */						/* the entry with a real */	first--;				/* device as device, or */    }						/* we are at the end of the */    while(last < nmnt - 1){			/* loop searching for the */	if(mounts[last + 1].dev != devno)	/* entry with the device */	  break;				/* as directory */	last++;    }    if(first < last){#if 0	/* all that nice stuff does not work in practice */	forever{	  if(lstat(mounts[found].devstr, &statb) < 0)	    break;	/* may never happen */	  if(S_ISBLK(statb.st_mode) || S_ISCHR(statb.st_mode))	    break;				/* we have a device here */	  for(i = first; i <= last; i++){	    if(i == found)		continue;	    if(!strcmp(mounts[found].devstr, mounts[i].dir))		break;	/* have a new entry with dir == dev of old entry */	  }	  if(i <= last)	    found = i;		/* continue with the found entry */	  else	    break;	/* if none found, we are at the end, no clue left */	}		/* stick with the entry found before (?) */#else	/* instead simply look for a real device */	n = 0;	for(i = first; i <= last; i++){	  if(!mounts[i].devstr || !mounts[i].typestr)	    continue;	  if(stat(mounts[i].devstr, &statb) < 0)	    continue;	  if(S_ISBLK(statb.st_mode) || S_ISCHR(statb.st_mode)){	    if(dnam && mounts[i].dir){		l = strlen(mounts[i].dir);		if(!strcmp(dnam, mounts[i].dir)			|| (!strncmp(dnam, mounts[i].dir, l)					 && FN_ISDIRSEP(dnam[l]))){		  n++;		  found = i;		}	    }	    else{		n++;		found = i;	    }	  }	}	if(n > 1)		cry_out_loud_shit("several devices",			mounts + first, last - first + 1);	if(n == 0){	/* another perverse thing, hope it only happens on Sun */	  n = 0;	/* a supervised automount point and the real mount */	  for(i = first; i <= last; i++){	/* have the same device number */	    if(!strstr(mounts[i].typestr, "auto")){	/* we prefer non-auto */	      if(dnam && mounts[i].dir){	/* i *hate* such hardcoded stuff */		l = strlen(mounts[i].dir);		if(!strcmp(dnam, mounts[i].dir)			|| (!strncmp(dnam, mounts[i].dir, l)					 && FN_ISDIRSEP(dnam[l]))){		  n++;		  found = i;		}	      }	      else{		n++;		found = i;	      }	    }	  }	  if(n > 1)		cry_out_loud_shit("several non-automount directories",			mounts + first, last - first + 1);	}#endif	mntptr = mounts + found;    }  }  ZFREE(dnam);  return(mntptr);}UChar *get_fstype_by_devno_dir(dev_t devno, UChar * dnam)	/* this is not MT-safe */{  static MntEnt	*mounts = NULL;  static Int32	nmounts = 0;  static UChar	*prev_type = NULL;  static dev_t	prev_dev;  MntEnt	*mntptr;  if(prev_type && prev_dev == devno)    return(prev_type);  if(!mounts){    mounts = get_all_mounts(&nmounts);    if(!mounts)	return(NULL);  }  mntptr = find_mnt_by_devno_dir(mounts, nmounts, devno, dnam);  if(!mntptr){    free_mounts(mounts);    mounts = get_all_mounts(&nmounts);    if(!mounts)	return(NULL);    mntptr = find_mnt_by_devno_dir(mounts, nmounts, devno, dnam);  }  prev_dev = devno;  prev_type = (mntptr ? mntptr->typestr : NULL);  return(prev_type);}voidfree_mounts(MntEnt * mounts){  MntEnt	*mntptr;  if( (mntptr = mounts) ){    while(mounts->dir){	free(mounts->dir);	ZFREE(mounts->typestr);	ZFREE(mounts->devstr);	mounts++;    }    free(mntptr);  }}static struct _fac_names_ {  char	*name;  int	value;} lfacilitynames[] = {#ifdef	LOG_AUTH    { "auth", LOG_AUTH },#endif#ifdef	LOG_AUTHPRIV    { "authpriv", LOG_AUTHPRIV },#endif#ifdef	LOG_CRON    { "cron", LOG_CRON },#endif#ifdef	LOG_DAEMON    { "daemon", LOG_DAEMON },#endif#ifdef	LOG_FTP    { "ftp", LOG_FTP },#endif#ifdef	LOG_KERN    { "kern", LOG_KERN },#endif#ifdef	LOG_LPR    { "lpr", LOG_LPR },#endif#ifdef	LOG_MAIL    { "mail", LOG_MAIL },#endif#ifdef	LOG_NEWS    { "news", LOG_NEWS },#endif#ifdef	LOG_AUTH    { "security", LOG_AUTH },		/* DEPRECATED */#endif    { "syslog", LOG_SYSLOG },	/* always there !!! wow !!! */#ifdef	LOG_USER    { "user", LOG_USER },#endif#ifdef	LOG_UUCP    { "uucp", LOG_UUCP },#endif#ifdef	LOG_LOCAL0    { "local0", LOG_LOCAL0 },#endif#ifdef	LOG_LOCAL1    { "local1", LOG_LOCAL1 },#endif#ifdef	LOG_LOCAL2    { "local2", LOG_LOCAL2 },#endif#ifdef	LOG_LOCAL3    { "local3", LOG_LOCAL3 },#endif#ifdef	LOG_LOCAL4    { "local4", LOG_LOCAL4 },#endif#ifdef	LOG_LOCAL5    { "local5", LOG_LOCAL5 },#endif#ifdef	LOG_LOCAL6    { "local6", LOG_LOCAL6 },#endif#ifdef	LOG_LOCAL7    { "local7", LOG_LOCAL7 },#endif    { NULL, -1 }  };Uns32syslog_facility_from_string(UChar * str){  struct _fac_names_  *fnamesptr;  for(fnamesptr = lfacilitynames; fnamesptr->name; fnamesptr++)    if(!strcmp(fnamesptr->name, str))	break;  return(fnamesptr->value);}Int32to_other_user(  uid_t		vuid,  gid_t		vgid,  UGIDS		*old_ugids){  Int32		i;  old_ugids->uid = geteuid();  old_ugids->gid = getegid();  ZFREE(old_ugids->gids);  i = get_groups(&(old_ugids->ngids), &(old_ugids->gids));  if(i)    return(i);  return(set_eff_ugids(vuid, vgid, 0, &vgid));}Int32to_org_user(UGIDS * old_ugids){  Int32		i;  i = set_eff_ugids(old_ugids->uid, old_ugids->gid, old_ugids->ngids, old_ugids->gids);  if(!i){    ZFREE(old_ugids->gids);    SETZERO(*old_ugids);  }  return(i);}intcreate_unix_socket(UChar * path){  struct sockaddr_un	addr;  int	usock, sock_optval;  if(!access(path, F_OK)){    usock = open_uxsock_conn(path);    if(usock >= 0){	close(usock);	errno = EADDRINUSE;	return(-2);    }    unlink(path);  }  usock = socket(AF_UNIX, SOCK_STREAM, 0);  if(usock >= 0){    SETZERO(addr);    addr.sun_family = AF_UNIX;    strcpy(addr.sun_path, path);    sock_optval = 1;    setsockopt(usock, SOL_SOCKET, SO_REUSEADDR,				(char *) &sock_optval, sizeof(int));    if(bind(usock, (struct sockaddr * ) (& addr), sizeof(addr))){	close(usock);	usock = -1;    }  }  return(usock);}intopen_uxsock_conn(UChar * path){  struct sockaddr_un	addr;  int	usock;  usock = socket(AF_UNIX, SOCK_STREAM, 0);  if(usock >= 0){    SETZERO(addr);    addr.sun_family = AF_UNIX;    strcpy(addr.sun_path, path);    if(connect(usock, (struct sockaddr *) (&addr), sizeof(addr))){	close(usock);	usock = -1;    }  }  return(usock);}#if 0/* implemented as macro in sysutils.h */Int32set_closeonexec(int fd){  int	fl;  fl = fcntl(fd, F_GETFD) | FD_CLOEXEC;  return(fcntl(fd, F_SETFD, fl));}#endif#endif	/* any PC-compiler *//************ end of $RCSfile: sysutils.c,v $ ******************/

⌨️ 快捷键说明

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