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

📄 tenex.c

📁 mgcp协议源代码。支持多种编码:g711
💻 C
📖 第 1 页 / 共 3 页
字号:
      }}/* Tenex mail fetch flags * Accepts: MAIL stream *	    sequence *	    option flags * Sniffs at file to get flags */void tenex_flags (MAILSTREAM *stream,char *sequence,long flags){  unsigned long i;  if (stream && LOCAL &&      ((flags & FT_UID) ? mail_uid_sequence (stream,sequence) :       mail_sequence (stream,sequence)))    for (i = 1; i <= stream->nmsgs; i++)      if (mail_elt (stream,i)->sequence) tenex_elt (stream,i);}/* TENEX mail fetch message header * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned header text length *	    option flags * Returns: message header in RFC822 format */char *tenex_header (MAILSTREAM *stream,unsigned long msgno,		    unsigned long *length,long flags){  char *s;  unsigned long i;  *length = 0;			/* default to empty */  if (flags & FT_UID) return "";/* UID call "impossible" */				/* get to header position */  lseek (LOCAL->fd,tenex_hdrpos (stream,msgno,&i),L_SET);  if (flags & FT_INTERNAL) {    if (i > LOCAL->buflen) {	/* resize if not enough space */      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get (LOCAL->buflen = i + 1);    }				/* slurp the data */    read (LOCAL->fd,LOCAL->buf,*length = i);  }  else {    s = (char *) fs_get (i + 1);/* get readin buffer */    s[i] = '\0';		/* tie off string */    read (LOCAL->fd,s,i);	/* slurp the data */				/* make CRLF copy of string */    *length = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s,i);    fs_give ((void **) &s);	/* free readin buffer */  }  return LOCAL->buf;}/* TENEX mail fetch message text (body only) * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned stringstruct *	    option flags * Returns: T, always */long tenex_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  char *s;  unsigned long i,j;  MESSAGECACHE *elt;				/* UID call "impossible" */  if (flags & FT_UID) return NIL;				/* get message status */  elt = tenex_elt (stream,msgno);				/* if message not seen */  if (!(flags & FT_PEEK) && !elt->seen) {    elt->seen = T;		/* mark message as seen */				/* recalculate status */    tenex_update_status (stream,msgno,T);    mm_flags (stream,msgno);  }				/* find header position */  i = tenex_hdrpos (stream,msgno,&j);  lseek (LOCAL->fd,i + j,L_SET);				/* go to text position */  if (flags & FT_INTERNAL) {	/* if internal representation wanted */    if (i > LOCAL->buflen) {	/* resize if not enough space */      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get (LOCAL->buflen = i + 1);    }				/* slurp the data */    read (LOCAL->fd,LOCAL->buf,i);  }  else {			/* get readin buffer */    s = (char *) fs_get ((i = tenex_size (stream,msgno) - j) + 1);    s[i] = '\0';		/* tie off string */    read (LOCAL->fd,s,i);	/* slurp the data */				/* make CRLF copy of string */    i = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s,i);    fs_give ((void **) &s);	/* free readin buffer */  }				/* set up stringstruct */  INIT (bs,mail_string,LOCAL->buf,i);  return T;			/* success */}/* Tenex mail modify flags * Accepts: MAIL stream *	    sequence *	    flag(s) *	    option flags */void tenex_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags){  struct stat sbuf;  if (!stream->rdonly) {	/* make sure the update takes */    fsync (LOCAL->fd);    fstat (LOCAL->fd,&sbuf);	/* get current write time */    LOCAL->filetime = sbuf.st_mtime;  }}/* Tenex mail per-message modify flags * Accepts: MAIL stream *	    message cache element */void tenex_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt){  struct stat sbuf;				/* maybe need to do a checkpoint? */  if (LOCAL->filetime && !LOCAL->shouldcheck) {    fstat (LOCAL->fd,&sbuf);	/* get current write time */    if (LOCAL->filetime < sbuf.st_mtime) LOCAL->shouldcheck = T;    LOCAL->filetime = 0;	/* don't do this test for any other messages */  }				/* recalculate status */  tenex_update_status (stream,elt->msgno,NIL);}/* Tenex mail ping mailbox * Accepts: MAIL stream * Returns: T if stream still alive, NIL if not */long tenex_ping (MAILSTREAM *stream){  unsigned long i = 1;  long r = T;  int ld;  char lock[MAILTMPLEN];  struct stat sbuf;  if (stream && LOCAL) {	/* only if stream already open */    fstat (LOCAL->fd,&sbuf);	/* get current file poop */    if (LOCAL->filetime && !(LOCAL->mustcheck || LOCAL->shouldcheck) &&	(LOCAL->filetime < sbuf.st_mtime)) LOCAL->shouldcheck = T;				/* check for changed message status */    if (LOCAL->mustcheck || LOCAL->shouldcheck) {      if (LOCAL->shouldcheck)	/* babble when we do this unilaterally */	mm_notify (stream,"[CHECK] Checking for flag updates",NIL);      while (i <= stream->nmsgs) tenex_elt (stream,i++);      LOCAL->mustcheck = LOCAL->shouldcheck = NIL;    }				/* get shared parse/append permission */    if ((sbuf.st_size != LOCAL->filesize) &&	((ld = lockfd (LOCAL->fd,lock,LOCK_SH)) >= 0)) {				/* parse resulting mailbox */      r = (tenex_parse (stream)) ? T : NIL;      unlockfd (ld,lock);	/* release shared parse/append permission */    }    if (LOCAL) {		/* stream must still be alive */				/* snarf if this is a read-write inbox */      if (stream->inbox && !stream->rdonly) {	tenex_snarf (stream);	fstat (LOCAL->fd,&sbuf);/* see if file changed now */	if ((sbuf.st_size != LOCAL->filesize) &&	    ((ld = lockfd (LOCAL->fd,lock,LOCK_SH)) >= 0)) {				/* parse resulting mailbox */	  r = (tenex_parse (stream)) ? T : NIL;	  unlockfd (ld,lock);	/* release shared parse/append permission */	}      }      else if ((sbuf.st_ctime > sbuf.st_atime) ||	       (sbuf.st_ctime > sbuf.st_mtime)) {	time_t tp[2];		/* whack the times if necessary */	LOCAL->filetime = tp[0] = tp[1] = time (0);	utime (stream->mailbox,tp);      }    }  }  return r;			/* return result of the parse */}/* Tenex mail check mailbox (reparses status too) * Accepts: MAIL stream */void tenex_check (MAILSTREAM *stream){				/* mark that a check is desired */  if (LOCAL) LOCAL->mustcheck = T;  if (tenex_ping (stream)) mm_log ("Check completed",(long) NIL);}/* Tenex mail snarf messages from system inbox * Accepts: MAIL stream */void tenex_snarf (MAILSTREAM *stream){  unsigned long i = 0;  unsigned long j,r,hdrlen,txtlen;  struct stat sbuf;  char *hdr,*txt,lock[MAILTMPLEN],tmp[MAILTMPLEN];  MESSAGECACHE *elt;  MAILSTREAM *sysibx = NIL;  int ld;				/* give up if can't get exclusive permission */  if ((time (0) < (LOCAL->lastsnarf + 30)) ||      (!strcmp (sysinbox (),stream->mailbox)) ||      ((ld = lockfd (LOCAL->fd,lock,LOCK_EX)) < 0)) return;  mm_critical (stream);		/* go critical */				/* see if anything there */  if (!stat (sysinbox (),&sbuf) && sbuf.st_size) {    fstat (LOCAL->fd,&sbuf);	/* yes, get current file size */				/* sizes match and can get sysibx mailbox? */    if ((sbuf.st_size == LOCAL->filesize) && 	(sysibx = mail_open (sysibx,sysinbox (),OP_SILENT)) &&	(!sysibx->rdonly) && (r = sysibx->nmsgs)) {				/* yes, go to end of file in our mailbox */      lseek (LOCAL->fd,sbuf.st_size,L_SET);				/* for each message in sysibx mailbox */      while (r && (++i <= sysibx->nmsgs)) {				/* snarf message from system INBOX */	hdr = cpystr (mail_fetchheader_full(sysibx,i,NIL,&hdrlen,FT_INTERNAL));	txt = mail_fetchtext_full (sysibx,i,&txtlen,FT_INTERNAL|FT_PEEK);	if (j = hdrlen + txtlen) {				/* calculate header line */	  mail_date (LOCAL->buf,elt = mail_elt (sysibx,i));	  sprintf (LOCAL->buf + strlen (LOCAL->buf),		   ",%lu;0000000000%02o\n",j,(unsigned)		   ((fSEEN * elt->seen) + (fDELETED * elt->deleted) +		    (fFLAGGED * elt->flagged) + (fANSWERED * elt->answered) +		    (fDRAFT * elt->draft)));				/* copy message */	  if ((write (LOCAL->fd,LOCAL->buf,strlen (LOCAL->buf)) < 0) ||	      (write (LOCAL->fd,hdr,hdrlen) < 0) ||	      (write (LOCAL->fd,txt,txtlen) < 0)) r = 0;	}	fs_give ((void **) &hdr);      }				/* make sure all the updates take */      if (fsync (LOCAL->fd)) r = 0;      if (r) {			/* delete all the messages we copied */	if (r == 1) strcpy (tmp,"1");	else sprintf (tmp,"1:%lu",r);	mail_flag (sysibx,tmp,"\\Deleted",ST_SET);	mail_expunge (sysibx);	/* now expunge all those messages */      }      else {	sprintf (LOCAL->buf,"Can't copy new mail: %s",strerror (errno));	mm_log (LOCAL->buf,ERROR);	ftruncate (LOCAL->fd,sbuf.st_size);      }      fstat (LOCAL->fd,&sbuf);	/* yes, get current file size */      LOCAL->filetime = sbuf.st_mtime;    }    if (sysibx) mail_close (sysibx);  }  mm_nocritical (stream);	/* release critical */  unlockfd (ld,lock);		/* release exclusive parse/append permission */  LOCAL->lastsnarf = time (0);	/* note time of last snarf */}/* Tenex mail expunge mailbox * Accepts: MAIL stream */void tenex_expunge (MAILSTREAM *stream){  struct stat sbuf;  off_t pos = 0;  int ld;  unsigned long i = 1;  unsigned long j,k,m,recent;  unsigned long n = 0;  unsigned long delta = 0;  char lock[MAILTMPLEN];  MESSAGECACHE *elt;  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);				/* do nothing if stream dead */  if (!tenex_ping (stream)) return;  if (stream->rdonly) {		/* won't do on readonly files! */    mm_log ("Expunge ignored on readonly mailbox",WARN);    return;  }  if (LOCAL->filetime && !LOCAL->shouldcheck) {    fstat (LOCAL->fd,&sbuf);	/* get current write time */    if (LOCAL->filetime < sbuf.st_mtime) LOCAL->shouldcheck = T;  }  /* The cretins who designed flock() created a window of vulnerability in   * upgrading locks from shared to exclusive or downgrading from exclusive   * to shared.  Rather than maintain the lock at shared status at a minimum,   * flock() actually *releases* the former lock.  Obviously they never talked   * to any database guys.  Fortunately, we have the parse/append permission   * lock.  If we require this lock before going exclusive on the mailbox,   * another process can not sneak in and steal the exclusive mailbox lock on   * us, because it will block on trying to get parse/append permission first.   */				/* get exclusive parse/append permission */  if ((ld = lockfd (LOCAL->fd,lock,LOCK_EX)) < 0) {    mm_log ("Unable to lock expunge mailbox",ERROR);    return;  }				/* get exclusive access */  if (flock (LOCAL->fd,LOCK_EX|LOCK_NB)) {    (*bn) (BLOCK_FILELOCK,NIL);    flock (LOCAL->fd,LOCK_SH);	/* recover previous lock */    (*bn) (BLOCK_NONE,NIL);    mm_log("Can't expunge because mailbox is in use by another process",ERROR);    unlockfd (ld,lock);		/* release exclusive parse/append permission */    return;  }  mm_critical (stream);		/* go critical */  recent = stream->recent;	/* get recent now that pinged and locked */  while (i <= stream->nmsgs) {	/* for each message */    elt = tenex_elt (stream,i);	/* get cache element */				/* number of bytes to smash or preserve */    k = elt->private.special.text.size + tenex_size (stream,i);    if (elt->deleted) {		/* if deleted */      if (elt->recent) --recent;/* if recent, note one less recent message */      delta += k;		/* number of bytes to delete */      mail_expunged (stream,i);	/* notify upper levels */      n++;			/* count up one more expunged message */    }    else if (i++ && delta) {	/* preserved message */				/* first byte to preserve */      j = elt->private.special.offset;      do {			/* read from source position */	m = min (k,LOCAL->buflen);	lseek (LOCAL->fd,j,L_SET);	read (LOCAL->fd,LOCAL->buf,m);	pos = j - delta;	/* write to destination position */	lseek (LOCAL->fd,pos,L_SET);	while (T) {	  lseek (LOCAL->fd,pos,L_SET);	  if (write (LOCAL->fd,LOCAL->buf,m) > 0) break;	  mm_notify (stream,strerror (errno),WARN);	  mm_diskerror (stream,errno,T);	}	pos += m;		/* new position */	j += m;			/* next chunk, perhaps */      } while (k -= m);		/* until done */				/* note the new address of this text */      elt->private.special.offset -= delta;    }				/* preserved but no deleted messages */    else pos = elt->private.special.offset + k;  }  if (n) {			/* truncate file after last message */    if (pos != (LOCAL->filesize -= delta)) {      sprintf (LOCAL->buf,"Calculated size mismatch %lu != %lu, delta = %lu",	       (unsigned long) pos,(unsigned long) LOCAL->filesize,delta);      mm_log (LOCAL->buf,WARN);      LOCAL->filesize = pos;	/* fix it then */    }    ftruncate (LOCAL->fd,LOCAL->filesize);    sprintf (LOCAL->buf,"Expunged %lu messages",n);				/* output the news */    mm_log (LOCAL->buf,(long) NIL);  }  else mm_log ("No messages deleted, so no update needed",(long) NIL);  fsync (LOCAL->fd);		/* force disk update */  fstat (LOCAL->fd,&sbuf);	/* get new write time */  LOCAL->filetime = sbuf.st_mtime;  mm_nocritical (stream);	/* release critical */				/* notify upper level of new mailbox size */  mail_exists (stream,stream->nmsgs);  mail_recent (stream,recent);  (*bn) (BLOCK_FILELOCK,NIL);  flock (LOCAL->fd,LOCK_SH);	/* allow sharers again */  (*bn) (BLOCK_NONE,NIL);  unlockfd (ld,lock);		/* release exclusive parse/append permission */}/* Tenex mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if success, NIL if failed */long tenex_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  struct stat sbuf;  time_t tp[2];  MESSAGECACHE *elt;  unsigned long i,j,k;  long ret = LONGT;  int fd,ld;  char file[MAILTMPLEN],lock[MAILTMPLEN];  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);				/* make sure valid mailbox */  if (!tenex_isvalid (mailbox,LOCAL->buf)) switch (errno) {  case ENOENT:			/* no such file? */    mm_notify (stream,"[TRYCREATE] Must create mailbox before copy",NIL);    return NIL;  case 0:			/* merely empty file? */    break;  case EINVAL:    if (pc) return (*pc) (stream,sequence,mailbox,options);    sprintf (LOCAL->buf,"Invalid Tenex-format mailbox name: %.80s",mailbox);    mm_log (LOCAL->buf,ERROR);    return NIL;  default:    if (pc) return (*pc) (stream,sequence,mailbox,options);    sprintf (LOCAL->buf,"Not a Tenex-format mailbox: %.80s",mailbox);    mm_log (LOCAL->buf,ERROR);    return NIL;  }  if (!((options & CP_UID) ? mail_uid_sequence (stream,sequence) :	mail_sequence (stream,sequence))) return NIL;				/* got file? */    if ((fd=open(tenex_file(file,mailbox),O_RDWR|O_CREAT,S_IREAD|S_IWRITE))<0) {    sprintf (LOCAL->buf,"Unable to open copy mailbox: %s",strerror (errno));    mm_log (LOCAL->buf,ERROR);    return NIL;  }  mm_critical (stream);		/* go critical */				/* get exclusive parse/append permission */  if ((ld = lockfd (fd,lock,LOCK_EX)) < 0) {    mm_log ("Unable to lock copy mailbox",ERROR);    return NIL;  }  fstat (fd,&sbuf);		/* get current file size */  lseek (fd,sbuf.st_size,L_SET);/* move to end of file */

⌨️ 快捷键说明

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