env_unix.c

来自「这是用C编写IMAP源代码」· C语言 代码 · 共 1,641 行 · 第 1/4 页

C
1,641
字号
  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];}/* Process rc file * Accepts: file name *	    .mminit flag * Don't even think of using this feature. */void dorc (char *file,long flag){  int i;  char *s,*t,*k,tmp[MAILTMPLEN],tmpx[MAILTMPLEN];  extern MAILSTREAM CREATEPROTO;  extern MAILSTREAM EMPTYPROTO;  DRIVER *d;  FILE *f;				/* no file or ill-advised usage */  if ((f = fopen (file ? file : SYSCONFIG,"r")) &&      (s = fgets (tmp,MAILTMPLEN,f)) && (t = strchr (s,'\n')) &&      (flag || (!strncmp (s,RISKPHRASE,sizeof (RISKPHRASE)-1) &&		(s = fgets (tmp,MAILTMPLEN,f)) && (t = strchr (s,'\n'))))) do {    *t++ = '\0';		/* tie off line, find second space */    if ((k = strchr (s,' ')) && (k = strchr (++k,' '))) {      *k++ = '\0';		/* tie off two words */      if (!compare_cstring (s,"set keywords") && !userFlags[0]) {	k = strtok (k,", ");	/* yes, get first keyword */				/* copy keyword list */	for (i = 0; k && i < NUSERFLAGS; ++i) if (strlen (k) <= MAXUSERFLAG) {	  if (userFlags[i]) fs_give ((void **) &userFlags[i]);	  userFlags[i] = cpystr (k);	  k = strtok (NIL,", ");	}	if (flag) break;	/* found "set keywords" in .mminit */      }      else if (!flag) {		/* none of these valid in .mminit */	if (myUserName) {	/* only valid if logged in */	  if (!compare_cstring (s,"set new-folder-format")) {	    if (!compare_cstring (k,"same-as-inbox"))	      createProto = ((d = mail_valid (NIL,"INBOX",NIL)) &&			     compare_cstring (d->name,"dummy")) ?			       ((*d->open) (NIL)) : &CREATEPROTO;	    else if (!compare_cstring (k,"system-standard"))	      createProto = &CREATEPROTO;	    else {		/* see if a driver name */	      for (d = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL);		   d && compare_cstring (d->name,k); d = d->next);	      if (d) createProto = (*d->open) (NIL);	      else {		/* duh... */		sprintf (tmpx,"Unknown new folder format in %s: %s",file,k);		MM_LOG (tmpx,WARN);	      }	    }	  }	  if (!compare_cstring (s,"set empty-folder-format")) {	    if (!compare_cstring (k,"same-as-inbox"))	      appendProto = ((d = mail_valid (NIL,"INBOX",NIL)) &&			     compare_cstring (d->name,"dummy")) ?			       ((*d->open) (NIL)) : &EMPTYPROTO;	    else if (!compare_cstring (k,"system-standard"))	      appendProto = &EMPTYPROTO;	    else {		/* see if a driver name */	      for (d = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL);		   d && compare_cstring (d->name,k); d = d->next);	      if (d) appendProto = (*d->open) (NIL);	      else {		/* duh... */		sprintf (tmpx,"Unknown empty folder format in %s: %s",file,k);		MM_LOG (tmpx,WARN);	      }	    }	  }	}	if (!compare_cstring (s,"set local-host")) {	  fs_give ((void **) &myLocalHost);	  myLocalHost = cpystr (k);	}	else if (!compare_cstring (s,"set news-active-file")) {	  fs_give ((void **) &newsActive);	  newsActive = cpystr (k);	}	else if (!compare_cstring (s,"set news-spool-directory")) {	  fs_give ((void **) &newsSpool);	  newsSpool = cpystr (k);	}	else if (!compare_cstring (s,"set news-state-file")) {	  fs_give ((void **) &myNewsrc);	  myNewsrc = cpystr (k);	}	else if (!compare_cstring (s,"set ftp-export-directory")) {	  fs_give ((void **) &ftpHome);	  ftpHome = cpystr (k);	}	else if (!compare_cstring (s,"set public-home-directory")) {	  fs_give ((void **) &publicHome);	  publicHome = cpystr (k);	}	else if (!compare_cstring (s,"set shared-home-directory")) {	  fs_give ((void **) &sharedHome);	  sharedHome = cpystr (k);	}	else if (!compare_cstring (s,"set system-inbox")) {	  fs_give ((void **) &sysInbox);	  sysInbox = cpystr (k);	}	else if (!compare_cstring (s,"set mail-subdirectory")) {	  fs_give ((void **) &mailsubdir);	  mailsubdir = cpystr (k);	}	else if (!compare_cstring (s,"set from-widget"))	  mail_parameters (NIL,SET_FROMWIDGET,			   compare_cstring (k,"header-only") ?			   VOIDT : NIL);	else if (!compare_cstring (s,"set rsh-command"))	  mail_parameters (NIL,SET_RSHCOMMAND,(void *) k);	else if (!compare_cstring (s,"set rsh-path"))	  mail_parameters (NIL,SET_RSHPATH,(void *) k);	else if (!compare_cstring (s,"set ssh-command"))	  mail_parameters (NIL,SET_SSHCOMMAND,(void *) k);	else if (!compare_cstring (s,"set ssh-path"))	  mail_parameters (NIL,SET_SSHPATH,(void *) k);	else if (!compare_cstring (s,"set tcp-open-timeout"))	  mail_parameters (NIL,SET_OPENTIMEOUT,(void *) atol (k));	else if (!compare_cstring (s,"set tcp-read-timeout"))	  mail_parameters (NIL,SET_READTIMEOUT,(void *) atol (k));	else if (!compare_cstring (s,"set tcp-write-timeout"))	  mail_parameters (NIL,SET_WRITETIMEOUT,(void *) atol (k));	else if (!compare_cstring (s,"set rsh-timeout"))	  mail_parameters (NIL,SET_RSHTIMEOUT,(void *) atol (k));	else if (!compare_cstring (s,"set ssh-timeout"))	  mail_parameters (NIL,SET_SSHTIMEOUT,(void *) atol (k));	else if (!compare_cstring (s,"set maximum-login-trials"))	  mail_parameters (NIL,SET_MAXLOGINTRIALS,(void *) atol (k));	else if (!compare_cstring (s,"set lookahead"))	  mail_parameters (NIL,SET_LOOKAHEAD,(void *) atol (k));	else if (!compare_cstring (s,"set prefetch"))	  mail_parameters (NIL,SET_PREFETCH,(void *) atol (k));	else if (!compare_cstring (s,"set close-on-error"))	  mail_parameters (NIL,SET_CLOSEONERROR,(void *) atol (k));	else if (!compare_cstring (s,"set imap-port"))	  mail_parameters (NIL,SET_IMAPPORT,(void *) atol (k));	else if (!compare_cstring (s,"set pop3-port"))	  mail_parameters (NIL,SET_POP3PORT,(void *) atol (k));	else if (!compare_cstring (s,"set uid-lookahead"))	  mail_parameters (NIL,SET_UIDLOOKAHEAD,(void *) atol (k));	else if (!compare_cstring (s,"set try-ssl-first"))	  mail_parameters (NIL,SET_TRYSSLFIRST,(void *) atol (k));	else if (!compare_cstring (s,"set mailbox-protection"))	  mbx_protection = atol (k);	else if (!compare_cstring (s,"set directory-protection"))	  dir_protection = atol (k);	else if (!compare_cstring (s,"set lock-protection"))	  lock_protection = atol (k);	else if (!compare_cstring (s,"set ftp-protection"))	  ftp_protection = atol (k);	else if (!compare_cstring (s,"set public-protection"))	  public_protection = atol (k);	else if (!compare_cstring (s,"set shared-protection"))	  shared_protection = atol (k);	else if (!compare_cstring (s,"set ftp-directory-protection"))	  ftp_dir_protection = atol (k);	else if (!compare_cstring (s,"set public-directory-protection"))	  public_dir_protection = atol (k);	else if (!compare_cstring (s,"set shared-directory-protection"))	  shared_dir_protection = atol (k);	else if (!compare_cstring (s,"set dot-lock-file-timeout"))	  locktimeout = atoi (k);	else if (!compare_cstring (s,"set disable-fcntl-locking"))	  disableFcntlLock = atoi (k);	else if (!compare_cstring (s,"set disable-lock-warning"))	  disableLockWarning = atoi (k);	else if (!compare_cstring (s,"set hide-dot-files"))	  hideDotFiles = atoi (k);	else if (!compare_cstring (s,"set list-maximum-level"))	  list_max_level = atol (k);	else if (!compare_cstring (s,"set trust-dns"))	  mail_parameters (NIL,SET_TRUSTDNS,(void *) atol (k));	else if (!compare_cstring (s,"set sasl-uses-ptr-name"))	  mail_parameters (NIL,SET_SASLUSESPTRNAME,(void *) atol (k));	else if (!compare_cstring (s,"set network-filesystem-stat-bug"))	  netfsstatbug = atoi (k);	else if (!file) {	/* only allowed in system init */	  if (!compare_cstring (s,"set black-box-directory") &&	      !blackBoxDir) blackBoxDir = cpystr (k);	  else if (!compare_cstring(s,"set black-box-default-home-directory")&&		   blackBoxDir && !blackBoxDefaultHome)	    blackBoxDefaultHome = cpystr (k);	  else if (!compare_cstring (s,"set anonymous-home-directory") &&		   !anonymousHome) anonymousHome = cpystr (k);	  else if (!compare_cstring (s,"set disable-plaintext"))	    disablePlaintext = atoi (k);	  else if (!compare_cstring (s,"set allowed-login-attempts"))	    logtry = atoi (k);	  else if (!compare_cstring (s,"set chroot-server"))	    closedBox = atoi (k);	  else if (!compare_cstring (s,"set restrict-mailbox-access")) {	    for (k = strtok (k,", "); k; k = strtok (NIL,", ")) {	      if (!compare_cstring (k,"root")) restrictBox |= RESTRICTROOT;	      else if (!compare_cstring (k,"otherusers"))		restrictBox |= RESTRICTOTHERUSER;	      else if (!compare_cstring (k,"all")) restrictBox = -1;	    }	  }	  else if (!compare_cstring (s,"set advertise-the-world"))	    advertisetheworld = atoi (k);	  else if (!compare_cstring (s,"set limited-advertise"))	    limitedadvertise = atoi (k);	  else if (!compare_cstring		   (s,"set disable-automatic-shared-namespaces"))	    noautomaticsharedns = atoi (k);	  else if (!compare_cstring (s,"set allow-user-config"))	    allowuserconfig = atoi (k);	  else if (!compare_cstring (s,"set allow-reverse-dns"))	    mail_parameters (NIL,SET_ALLOWREVERSEDNS,(void *) atol (k));	}      }    }  } while ((s = fgets (tmp,MAILTMPLEN,f)) && (t = strchr (s,'\n')));  if (f) fclose (f);		/* flush the file */}/* INBOX create function for tmail/dmail use only * Accepts: mail stream *	    path name buffer, preloaded with driver-dependent path * Returns: T on success, NIL on failure * * This routine is evil and a truly incredible kludge.  It is private for * tmail/dmail and is not supported for any other application. */long path_create (MAILSTREAM *stream,char *path){  long ret;  short rsave = restrictBox;  restrictBox = NIL;		/* can't restrict */  if (blackBox) {		/* if black box */				/* toss out driver dependent names */    printf (path,"%s/INBOX",mymailboxdir ());    blackBox = NIL;		/* well that's evil - evil is going on */    ret = mail_create (stream,path);    blackBox = T;		/* restore the box */  }				/* easy thing otherwise */  else ret = mail_create (stream,path);  restrictBox = rsave;		/* restore restrictions */  return ret;}/* 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 + =
减小字号Ctrl + -
显示快捷键?