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

📄 env_ami.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  }  return dst;			/* return final name */}/* Dot-lock file locker * Accepts: file name to lock *	    destination buffer for lock file name *	    open file description on file name to lock * Returns: T if success, NIL if failure */long dotlock_lock (char *file,DOTLOCK *base,int fd){  int i = locktimeout * 60;  int j,mask,retry,pi[2],po[2];  char *s,tmp[MAILTMPLEN];  struct stat sb;				/* flush absurd file name */  if (strlen (file) > 512) return NIL;				/* build lock filename */  sprintf (base->lock,"%s.lock",file);				/* assume no pipe */  base->pipei = base->pipeo = -1;  do {				/* make sure not symlink */    if (!(j = chk_notsymlink (base->lock,&sb))) return NIL;				/* time out if file older than 5 minutes */    if ((j > 0) && ((time (0)) >= (sb.st_ctime + locktimeout * 60))) i = 0;				/* try to create the lock */    if ((j = open (name,O_WRONLY|O_CREAT|O_EXCL,(int) lock_protection)) >= 0) {      close (i);		/* make the file, now close it */      chmod (base->lock,(int) lock_protection);      return LONGT;    }    if (errno == EEXIST) {	/* already locked? */      retry = -1;		/* can try again */      if (!(i%15)) {		/* time to notify? */	sprintf (tmp,"Mailbox %.80s is locked, will override in %d seconds...",		 file,i);	mm_log (tmp,WARN);      }      sleep (1);		/* wait 1 second before next try */    }    else retry = i = 0;		/* hard failure, no more retries */  } while (i--);		/* until out of retries */  if (retry < 0) {		/* still returning retry after locktimeout? */    if (!(j = chk_notsymlink (base->lock,&sb))) return NIL;    if ((j > 0) && ((time (0)) < (sb.st_ctime + locktimeout * 60))) {      sprintf (tmp,"Mailbox vulnerable - seizing %ld second old lock",	       (long) (time (0) - sb.st_ctime));      mm_log (tmp,WARN);    }    mask = umask (0);    unlink (base->lock);	/* try to remove the old file */				/* seize the lock */    if ((i = open (base->lock,O_WRONLY|O_CREAT,(int) lock_protection)) >= 0) {      close (i);		/* don't need descriptor any more */      sprintf (tmp,"Mailbox %.80s lock overridden",file);      mm_log (tmp,NIL);      chmod (base->lock,(int) lock_protection);      umask (mask)		/* restore old umask */      return LONGT;    }    umask (mask)		/* restore old umask */  }  if (fd >= 0) switch (errno) {  case EACCES:			/* protection failure? */				/* make command pipes */    if (!stat (LOCKPGM,&sb) && (pipe (pi) >= 0)) {      if (pipe (po) >= 0) {	if (!(j = fork ())) {	/* make inferior process */	  if (!fork ()) {	/* make grandchild so it's inherited by init */	    char *argv[4];				/* prepare argument vector */	    sprintf (tmp,"%d",fd);	    argv[0] = LOCKPGM; argv[1] = tmp;	    argv[2] = file; argv[3] = NIL;				/* set parent's I/O to my O/I */	    dup2 (pi[1],1); dup2 (pi[1],2); dup2 (po[0],0);				/* close all unnecessary descriptors */	    for (j = max (20,max (max (pi[0],pi[1]),max(po[0],po[1])));		 j >= 3; --j) if (j != fd) close (j);				/* be our own process group */	    setpgrp (0,getpid ());				/* now run it */	    execv (argv[0],argv);	  }	  _exit (1);		/* child is done */	}	else if (j > 0) {	/* reap child; grandchild now owned by init */	  grim_pid_reap (j,NIL);				/* read response from locking program */	  if ((read (pi[0],tmp,1) == 1) && (tmp[0] == '+')) {				/* success, record pipes */	    base->pipei = pi[0]; base->pipeo = po[1];				/* close child's side of the pipes */	    close (pi[1]); close (po[0]);	    return LONGT;	  }	}	close (po[0]); close (po[1]);      }      close (pi[0]); close (pi[1]);    }				/* find directory/file delimiter */    if (s = strrchr (base->lock,'/')) {      *s = '\0';		/* tie off at directory */      sprintf(tmp,		/* generate default message */	      "Mailbox vulnerable - directory %.80s must have 1777 protection",	      base->lock);				/* definitely not 1777 if can't stat */      mask = stat (base->lock,&sb) ? 0 : (sb.st_mode & 1777);      *s = '/';			/* restore lock name */      if (mask != 1777) {	/* default warning if not 1777 */	MM_LOG (tmp,WARN);	break;      }    }  default:    sprintf (tmp,"Mailbox vulnerable - error creating %.80s: %s",	     base->lock,strerror (errno));    mm_log (tmp,WARN);		/* this is probably not good */    break;  }  base->lock[0] = '\0';		/* don't use lock files */  return NIL;}/* Dot-lock file unlocker * Accepts: lock file name * Returns: T if success, NIL if failure */long dotlock_unlock (DOTLOCK *base){  long ret = LONGT;  if (base && base->lock[0]) {    if (base->pipei >= 0) {	/* if running through a pipe unlocker */      ret = (write (base->pipeo,"+",1) == 1);				/* nuke the pipes */      close (base->pipei); close (base->pipeo);    }    else ret = !unlink (base->lock);  }  return ret;}/* Lock file name * Accepts: scratch buffer *	    file name *	    type of locking operation (LOCK_SH or LOCK_EX) *	    pointer to return PID of locker * Returns: file descriptor of lock or negative if error */int lockname (char *lock,char *fname,int op,long *pid){  struct stat sbuf;  *pid = 0;			/* no locker PID */  return stat (fname,&sbuf) ? -1 : lock_work (lock,&sbuf,op,pid);}/* Lock file descriptor * Accepts: file descriptor *	    lock file name buffer *	    type of locking operation (LOCK_SH or LOCK_EX) * Returns: file descriptor of lock or negative if error */int lockfd (int fd,char *lock,int op){  struct stat sbuf;  return fstat (fd,&sbuf) ? -1 : lock_work (lock,&sbuf,op,NIL);}/* Lock file name worker * Accepts: lock file name *	    pointer to stat() buffer *	    type of locking operation (LOCK_SH or LOCK_EX) *	    pointer to return PID of locker * Returns: file descriptor of lock or negative if error */int lock_work (char *lock,void *sb,int op,long *pid){  struct stat lsb,fsb;  struct stat *sbuf = (struct stat *) sb;  char tmp[MAILTMPLEN];  long i;  int fd;  int mask = umask (0);  if (pid) *pid = 0;		/* initialize return PID */				/* make temporary lock file name */  sprintf (lock,"%s/.%lx.%lx","/tmp",	   (unsigned long) sbuf->st_dev,(unsigned long) sbuf->st_ino);  while (T) {			/* until get a good lock */    do switch ((int) chk_notsymlink (lock,&lsb)) {    case 1:			/* exists just once */      if (((fd = open (lock,O_RDWR,lock_protection)) >= 0) ||	  (errno != ENOENT) || (chk_notsymlink (lock,&lsb) >= 0)) break;    case -1:			/* name doesn't exist */      fd = open (lock,O_RDWR|O_CREAT|O_EXCL,lock_protection);      break;    default:			/* multiple hard links */      mm_log ("hard link to lock name",ERROR);      syslog (LOG_CRIT,"SECURITY PROBLEM: hard link to lock name: %.80s",lock);    case 0:			/* symlink (already did syslog) */      umask (mask);		/* restore old mask */      return -1;		/* fail: no lock file */    } while ((fd < 0) && (errno == EEXIST));    if (fd < 0) {		/* failed to get file descriptor */      syslog (LOG_INFO,"Mailbox lock file %s open failure: %s",lock,	      strerror (errno));      if (stat ("/tmp",&lsb))	syslog (LOG_CRIT,"SYSTEM ERROR: no /tmp: %s",strerror (errno));      else if ((lsb.st_mode & 01777) != 01777)	mm_log ("Can't lock for write: /tmp must have 1777 protection",WARN);      umask (mask);		/* restore old mask */      return -1;		/* fail: can't open lock file */    }				/* non-blocking form */    if (op & LOCK_NB) i = flock (fd,op);    else {			/* blocking form */      (*mailblocknotify) (BLOCK_FILELOCK,NIL);      i = flock (fd,op);      (*mailblocknotify) (BLOCK_NONE,NIL);    }    if (i) {			/* failed, get other process' PID */      if (pid && !fstat (fd,&fsb) && (i = min (fsb.st_size,MAILTMPLEN-1)) &&	  (read (fd,tmp,i) == i) && !(tmp[i] = 0) && ((i = atol (tmp)) > 0))	*pid = i;      close (fd);		/* failed, give up on lock */      umask (mask);		/* restore old mask */      return -1;		/* fail: can't lock */    }				/* make sure this lock is good for us */    if (!lstat (lock,&lsb) && ((lsb.st_mode & S_IFMT) != S_IFLNK) &&	!fstat (fd,&fsb) && (lsb.st_dev == fsb.st_dev) &&	(lsb.st_ino == fsb.st_ino) && (fsb.st_nlink == 1)) break;    close (fd);			/* lock not right, drop fd and try again */  }				/* make sure mode OK (don't use fchmod()) */  chmod (lock,(int) lock_protection);  umask (mask);			/* restore old mask */  return fd;			/* success */}/* Check to make sure not a symlink * Accepts: file name *	    stat buffer * Returns: -1 if doesn't exist, NIL if symlink, else number of hard links */long chk_notsymlink (char *name,void *sb){  struct stat *sbuf = (struct stat *) sb;				/* name exists? */  if (lstat (name,sbuf)) return -1;				/* forbid symbolic link */  if ((sbuf->st_mode & S_IFMT) == S_IFLNK) {    mm_log ("symbolic link on lock name",ERROR);    syslog (LOG_CRIT,"SECURITY PROBLEM: symbolic link on lock name: %.80s",	    name);    return NIL;  }  return (long) sbuf->st_nlink;	/* return number of hard links */}/* Unlock file descriptor * Accepts: file descriptor *	    lock file name from lockfd() */void unlockfd (int fd,char *lock){				/* delete the file if no sharers */  if (!flock (fd,LOCK_EX|LOCK_NB)) unlink (lock);  flock (fd,LOCK_UN);		/* unlock it */  close (fd);			/* close it */}/* Set proper file protection for mailbox * Accepts: mailbox name *	    actual file path name * Returns: T, always */long set_mbx_protections (char *mailbox,char *path){  struct stat sbuf;  int mode = (int) mbx_protection;  if (*mailbox == '#') {	/* possible namespace? */      if (((mailbox[1] == 'f') || (mailbox[1] == 'F')) &&	  ((mailbox[2] == 't') || (mailbox[2] == 'T')) &&	  ((mailbox[3] == 'p') || (mailbox[3] == 'P')) &&	  (mailbox[4] == '/')) mode = (int) ftp_protection;      else if (((mailbox[1] == 'p') || (mailbox[1] == 'P')) &&	       ((mailbox[2] == 'u') || (mailbox[2] == 'U')) &&	       ((mailbox[3] == 'b') || (mailbox[3] == 'B')) &&	       ((mailbox[4] == 'l') || (mailbox[4] == 'L')) &&	       ((mailbox[5] == 'i') || (mailbox[5] == 'I')) &&	       ((mailbox[6] == 'c') || (mailbox[6] == 'C')) &&	       (mailbox[7] == '/')) mode = (int) public_protection;      else if (((mailbox[1] == 's') || (mailbox[1] == 'S')) &&	       ((mailbox[2] == 'h') || (mailbox[2] == 'H')) &&	       ((mailbox[3] == 'a') || (mailbox[3] == 'A')) &&	       ((mailbox[4] == 'r') || (mailbox[4] == 'R')) &&	       ((mailbox[5] == 'e') || (mailbox[5] == 'E')) &&	       ((mailbox[6] == 'd') || (mailbox[6] == 'D')) &&	       (mailbox[7] == '/')) mode = (int) shared_protection;  }				/* if a directory */  if (!stat (path,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR)) {				/* set owner search if allow read or write */    if (mode & 0600) mode |= 0100;    if (mode & 060) mode |= 010;/* set group search if allow read or write */    if (mode & 06) mode |= 01;	/* set world search if allow read or write */				/* preserve directory SGID bit */    if (sbuf.st_mode & S_ISGID) mode |= S_ISGID;  }  chmod (path,mode);		/* set the new protection, ignore failure */  return LONGT;}/* Get proper directory protection * Accepts: mailbox name * Returns: directory mode, always */long get_dir_protection (char *mailbox){  if (*mailbox == '#') {	/* possible namespace? */      if (((mailbox[1] == 'f') || (mailbox[1] == 'F')) &&	  ((mailbox[2] == 't') || (mailbox[2] == 'T')) &&	  ((mailbox[3] == 'p') || (mailbox[3] == 'P')) &&	  (mailbox[4] == '/')) return ftp_dir_protection;      else if (((mailbox[1] == 'p') || (mailbox[1] == 'P')) &&	       ((mailbox[2] == 'u') || (mailbox[2] == 'U')) &&	       ((mailbox[3] == 'b') || (mailbox[3] == 'B')) &&	       ((mailbox[4] == 'l') || (mailbox[4] == 'L')) &&	       ((mailbox[5] == 'i') || (mailbox[5] == 'I')) &&	       ((mailbox[6] == 'c') || (mailbox[6] == 'C')) &&	       (mailbox[7] == '/')) return public_dir_protection;      else if (((mailbox[1] == 's') || (mailbox[1] == 'S')) &&	       ((mailbox[2] == 'h') || (mailbox[2] == 'H')) &&	       ((mailbox[3] == 'a') || (mailbox[3] == 'A')) &&	       ((mailbox[4] == 'r') || (mailbox[4] == 'R')) &&	       ((mailbox[5] == 'e') || (mailbox[5] == 'E')) &&	       ((mailbox[6] == 'd') || (mailbox[6] == 'D')) &&	       (mailbox[7] == '/')) return shared_dir_protection;  }  return dir_protection;}/* Determine default prototype stream to user * Accepts: type (NIL for create, T for append) * Returns: default prototype stream */MAILSTREAM *default_proto (long type){  myusername ();		/* make sure initialized */				/* return default driver's prototype */  return type ? appendProto : createProto;}/* Set up user flags for stream * Accepts: MAIL stream * Returns: MAIL stream with user flags set up */MAILSTREAM *user_flags (MAILSTREAM *stream){  int i;  myusername ();		/* make sure initialized */  for (i = 0; i < NUSERFLAGS && userFlags[i]; ++i)    if (!stream->user_flags[i]) stream->user_flags[i] = cpystr (userFlags[i]);  return stream;}/* Return nth user flag * Accepts: user flag number * Returns: flag */char *default_user_flag (unsigned long i){  myusername ();		/* make sure initialized */  return userFlags[i];}/* Default block notify routine * Accepts: reason for calling *	    data * Returns: data */void *mm_blocknotify (int reason,void *data){  void *ret = data;  switch (reason) {  case BLOCK_SENSITIVE:		/* entering sensitive code */    ret = (void *) alarm (0);    break;  case BLOCK_NONSENSITIVE:	/* exiting sensitive code */    if ((unsigned int) data) alarm ((unsigned int) data);    break;  default:			/* ignore all other reasons */    break;  }  return ret;}

⌨️ 快捷键说明

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