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

📄 imapd.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    *v = '\0';			/* tie off string */    *size = v - s;		/* return size */    break;  case '{':			/* literal string */    s = *arg + 1;		/* get size */    if (!isdigit (*s)) return NIL;    if ((*size = i = strtoul (s,&t,10)) > MAXCLIENTLIT) {      mm_notify (NIL,"Absurdly long client literal",ERROR);      syslog (LOG_INFO,"Absurdly long client literal user=%.80s host=%.80s",	      user ? user : "???",tcp_clienthost ());      return NIL;    }				/* validate end of literal */    if (!t || (*t != '}') || t[1]) return NIL;    if (litsp >= LITSTKLEN) {	/* make sure don't overflow stack */      mm_notify (NIL,"Too many literals in command",ERROR);      return NIL;    }    PSOUT (argrdy);		/* tell client ready for argument */    PFLUSH;			/* dump output buffer */				/* get a literal buffer */    s = v = litstk[litsp++] = (char *) fs_get (i+1);				/* get literal under timeout */    alarm ((state != LOGIN) ? TIMEOUT : LOGINTIMEOUT);    while (i--) *v++ = inchar ();    alarm (0);			/* stop timeout */    *v++ = NIL;			/* make sure string tied off */    				/* get new command tail */    slurp ((*arg = v = t),TMPLEN - (t - cmdbuf));    if (!strchr (t,'\012')) return flush ();				/* reset strtok mechanism, tie off if done */    if (!strtok (t,"\015\012")) *t = '\0';    break;  }  if (*del = *t) {		/* have a delimiter? */    *t++ = '\0';		/* yes, stomp on it */    *arg = t;			/* update argument pointer */  }  else *arg = NIL;		/* no more arguments */  return s;}/* Snarf a command argument (simple jacket into parse_astring()) * Accepts: pointer to argument text pointer * Returns: argument */char *snarf (char **arg){  unsigned long i;  char c;  char *s = parse_astring (arg,&i,&c);  return ((c == ' ') || !c) ? s : NIL;}/* Snarf a list command argument (simple jacket into parse_astring()) * Accepts: pointer to argument text pointer * Returns: argument */char *snarf_list (char **arg){  unsigned long i;  char c;  char *s,*t;  if (!*arg) return NIL;	/* better be an argument */  switch (**arg) {  default:			/* atom and/or wildcard chars */    for (s = t = *arg, i = 0;	 (*t > ' ') && (*t != '(') && (*t != ')') && (*t != '{') &&	 (*t != '"') && (*t != '\\'); ++t,++i);    if (c = *t) {		/* have a delimiter? */      *t++ = '\0';		/* stomp on it */      *arg = t;			/* update argument pointer */    }    else *arg = NIL;    break;  case ')': case '\\': case '\0': case ' ':    return NIL;			/* empty name is bogus */  case '"':			/* quoted string? */  case '{':			/* or literal? */    s = parse_astring (arg,&i,&c);    break;  }  return ((c == ' ') || !c) ? s : NIL;}/* Get a list of header lines * Accepts: pointer to string pointer *	    pointer to list flag * Returns: string list */STRINGLIST *parse_stringlist (char **s,int *list){  char c = ' ',*t;  unsigned long i;  STRINGLIST *ret = NIL,*cur = NIL;  if (*s && **s == '(') {	/* proper list? */    ++*s;			/* for each item in list */    while ((c == ' ') && (t = parse_astring (s,&i,&c))) {				/* get new block */      if (cur) cur = cur->next = mail_newstringlist ();      else cur = ret = mail_newstringlist ();				/* note text */      cur->text.data = (unsigned char *) fs_get (i + 1);      memcpy (cur->text.data,t,i);      cur->text.size = i;		/* and size */    }				/* must be end of list */    if (c != ')') mail_free_stringlist (&ret);  }  if (t = *s) {			/* need to reload strtok() state? */				/* end of a list? */    if (*list && (*t == ')') && !t[1]) *list = NIL;    else {      *--t = ' ';		/* patch a space back in */      *--t = 'x';		/* and a hokey character before that */      t = strtok (t," ");	/* reset to *s */    }  }  return ret;}/* Parse search criteria * Accepts: search program to write criteria into *	    pointer to argument text pointer *	    maximum message number *	    maximum UID *	    logical nesting depth * Returns: T if success, NIL if error */long parse_criteria (SEARCHPGM *pgm,char **arg,unsigned long maxmsg,		     unsigned long maxuid,unsigned long depth){  if (arg && *arg) {		/* must be an argument */				/* parse criteria */    do if (!parse_criterion (pgm,arg,maxmsg,maxuid,depth)) return NIL;				/* as long as a space delimiter */    while (**arg == ' ' && (*arg)++);				/* failed if not end of criteria */    if (**arg && **arg != ')') return NIL;  }  return T;			/* success */}/* Parse a search criterion * Accepts: search program to write criterion into *	    pointer to argument text pointer *	    maximum message number *	    maximum UID *	    logical nesting depth * Returns: T if success, NIL if error */long parse_criterion (SEARCHPGM *pgm,char **arg,unsigned long maxmsg,		      unsigned long maxuid,unsigned long depth){  unsigned long i;  char c = NIL,*s,*t,*v,*tail,*del;  SEARCHSET **set;  SEARCHPGMLIST **not;  SEARCHOR **or;  SEARCHHEADER **hdr;  long ret = NIL;				/* better be an argument */  if ((depth > 50) || !(arg && *arg));  else if (**arg == '(') {	/* list of criteria? */    (*arg)++;			/* yes, parse the criteria */    if (parse_criteria (pgm,arg,maxmsg,maxuid,depth+1) && **arg == ')') {      (*arg)++;			/* skip closing paren */      ret = T;			/* successful parse of list */    }  }  else {			/* find end of criterion */    if (!(tail = strpbrk ((s = *arg)," )"))) tail = *arg + strlen (*arg);    c = *(del = tail);		/* remember the delimiter */    *del = '\0';		/* tie off criterion */    switch (*ucase (s)) {	/* dispatch based on character */    case '*':			/* sequence */    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':      if (*(set = &pgm->msgno)){/* already a sequence? */				/* silly, but not as silly as the client! */	for (not = &pgm->search_not; *not; not = &(*not)->next);	*not = mail_newsearchpgmlist ();	set = &((*not)->pgm->search_not = mail_newsearchpgmlist ())->pgm->msgno;      }      ret = crit_set (set,&s,maxmsg) && (tail == s);      break;    case 'A':			/* possible ALL, ANSWERED */      if (!strcmp (s+1,"LL")) ret = T;      else if (!strcmp (s+1,"NSWERED")) ret = pgm->answered = T;      break;    case 'B':			/* possible BCC, BEFORE, BODY */      if (!strcmp (s+1,"CC") && c == ' ' && *++tail)	ret = crit_string (&pgm->bcc,&tail);      else if (!strcmp (s+1,"EFORE") && c == ' ' && *++tail)	ret = crit_date (&pgm->before,&tail);      else if (!strcmp (s+1,"ODY") && c == ' ' && *++tail)	ret = crit_string (&pgm->body,&tail);      break;    case 'C':			/* possible CC */      if (!strcmp (s+1,"C") && c == ' ' && *++tail)	ret = crit_string (&pgm->cc,&tail);      break;    case 'D':			/* possible DELETED */      if (!strcmp (s+1,"ELETED")) ret = pgm->deleted = T;      if (!strcmp (s+1,"RAFT")) ret = pgm->draft = T;      break;    case 'F':			/* possible FLAGGED, FROM */      if (!strcmp (s+1,"LAGGED")) ret = pgm->flagged = T;      else if (!strcmp (s+1,"ROM") && c == ' ' && *++tail)	ret = crit_string (&pgm->from,&tail);      break;    case 'H':			/* possible HEADER */      if (!strcmp (s+1,"EADER") && c == ' ' && *(v = tail + 1) &&	  (s = parse_astring (&v,&i,&c)) && i && c == ' ' &&	  (t = parse_astring (&v,&i,&c))) {	for (hdr = &pgm->header; *hdr; hdr = &(*hdr)->next);	*hdr = mail_newsearchheader (s,t);				/* update tail, restore delimiter */	*(tail = v ? v - 1 : t + i) = c;	ret = T;		/* success */      }      break;    case 'K':			/* possible KEYWORD */      if (!strcmp (s+1,"EYWORD") && c == ' ' && *++tail)	ret = crit_string (&pgm->keyword,&tail);      break;    case 'L':      if (!strcmp (s+1,"ARGER") && c == ' ' && *++tail)	ret = crit_number (&pgm->larger,&tail);      break;    case 'N':			/* possible NEW, NOT */      if (!strcmp (s+1,"EW")) ret = pgm->recent = pgm->unseen = T;      else if (!strcmp (s+1,"OT") && c == ' ' && *++tail) {	for (not = &pgm->search_not; *not; not = &(*not)->next);	*not = mail_newsearchpgmlist ();	ret = parse_criterion ((*not)->pgm,&tail,maxmsg,maxuid,depth+1);      }      break;    case 'O':			/* possible OLD, ON */      if (!strcmp (s+1,"LD")) ret = pgm->old = T;      else if (!strcmp (s+1,"N") && c == ' ' && *++tail)	ret = crit_date (&pgm->on,&tail);      else if (!strcmp (s+1,"R") && c == ' ') {	for (or = &pgm->search_or; *or; or = &(*or)->next);	*or = mail_newsearchor ();	ret = *++tail && parse_criterion((*or)->first,&tail,maxmsg,maxuid,					 depth+1) && *tail == ' ' && *++tail &&	    parse_criterion ((*or)->second,&tail,maxmsg,maxuid,depth+1);      }      break;    case 'R':			/* possible RECENT */      if (!strcmp (s+1,"ECENT")) ret = pgm->recent = T;      break;    case 'S':			/* possible SEEN, SINCE, SUBJECT */      if (!strcmp (s+1,"EEN")) ret = pgm->seen = T;      else if (!strcmp (s+1,"ENTBEFORE") && c == ' ' && *++tail)	ret = crit_date (&pgm->sentbefore,&tail);      else if (!strcmp (s+1,"ENTON") && c == ' ' && *++tail)	ret = crit_date (&pgm->senton,&tail);      else if (!strcmp (s+1,"ENTSINCE") && c == ' ' && *++tail)	ret = crit_date (&pgm->sentsince,&tail);      else if (!strcmp (s+1,"INCE") && c == ' ' && *++tail)	ret = crit_date (&pgm->since,&tail);      else if (!strcmp (s+1,"MALLER") && c == ' ' && *++tail)	ret = crit_number (&pgm->smaller,&tail);      else if (!strcmp (s+1,"UBJECT") && c == ' ' && *++tail)	ret = crit_string (&pgm->subject,&tail);      break;    case 'T':			/* possible TEXT, TO */      if (!strcmp (s+1,"EXT") && c == ' ' && *++tail)	ret = crit_string (&pgm->text,&tail);      else if (!strcmp (s+1,"O") && c == ' ' && *++tail)	ret = crit_string (&pgm->to,&tail);      break;    case 'U':			/* possible UID, UN* */      if (!strcmp (s+1,"ID") && c== ' ' && *++tail) {	if (*(set = &pgm->uid)){/* already a sequence? */				/* silly, but not as silly as the client! */	  for (not = &pgm->search_not; *not; not = &(*not)->next);	  *not = mail_newsearchpgmlist ();	  set = &((*not)->pgm->search_not = mail_newsearchpgmlist ())->pgm->uid;	}	ret = crit_set (set,&tail,maxuid);      }      else if (!strcmp (s+1,"NANSWERED")) ret = pgm->unanswered = T;      else if (!strcmp (s+1,"NDELETED")) ret = pgm->undeleted = T;      else if (!strcmp (s+1,"NDRAFT")) ret = pgm->undraft = T;      else if (!strcmp (s+1,"NFLAGGED")) ret = pgm->unflagged = T;      else if (!strcmp (s+1,"NKEYWORD") && c == ' ' && *++tail)	ret = crit_string (&pgm->unkeyword,&tail);      else if (!strcmp (s+1,"NSEEN")) ret = pgm->unseen = T;      break;    default:			/* oh dear */      break;    }    if (ret) {			/* only bother if success */      *del = c;			/* restore delimiter */      *arg = tail;		/* update argument pointer */    }  }  return ret;			/* return more to come */}/* Parse a search date criterion * Accepts: date to write into *	    pointer to argument text pointer * Returns: T if success, NIL if error */long crit_date (unsigned short *date,char **arg){				/* handle quoted form */  if (**arg != '"') return crit_date_work (date,arg);  (*arg)++;			/* skip past opening quote */  if (!(crit_date_work (date,arg) && (**arg == '"'))) return NIL;  (*arg)++;			/* skip closing quote */  return T;}/* Worker routine to parse a search date criterion * Accepts: date to write into *	    pointer to argument text pointer * Returns: T if success, NIL if error */long crit_date_work (unsigned short *date,char **arg){  int d,m,y;				/* day */  if (isdigit (d = *(*arg)++) || ((d == ' ') && isdigit (**arg))) {    if (d == ' ') d = 0;	/* leading space */    else d -= '0';		/* first digit */    if (isdigit (**arg)) {	/* if a second digit */      d *= 10;			/* slide over first digit */      d += *(*arg)++ - '0';	/* second digit */    }    if ((**arg == '-') && (y = *++(*arg))) {      m = (y >= 'a' ? y - 'a' : y - 'A') * 1024;      if ((y = *++(*arg))) {	m += (y >= 'a' ? y - 'a' : y - 'A') * 32;	if ((y = *++(*arg))) {	  m += (y >= 'a' ? y - 'a' : y - 'A');	  switch (m) {		/* determine the month */	  case (('J'-'A') * 1024) + (('A'-'A') * 32) + ('N'-'A'): m = 1; break;	  case (('F'-'A') * 1024) + (('E'-'A') * 32) + ('B'-'A'): m = 2; break;	  case (('M'-'A') * 1024) + (('A'-'A') * 32) + ('R'-'A'): m = 3; break;	  case (('A'-'A') * 1024) + (('P'-'A') * 32) + ('R'-'A'): m = 4; break;	  case (('M'-'A') * 1024) + (('A'-'A') * 32) + ('Y'-'A'): m = 5; break;	  case (('J'-'A') * 1024) + (('U'-'A') * 32) + ('N'-'A'): m = 6; break;	  case (('J'-'A') * 1024) + (('U'-'A') * 32) + ('L'-'A'): m = 7; break;	  case (('A'-'A') * 1024) + (('U'-'A') * 32) + ('G'-'A'): m = 8; break;	  case (('S'-'A') * 1024) + (('E'-'A') * 32) + ('P'-'A'): m = 9; break;	  case (('O'-'A') * 1024) + (('C'-'A') * 32) + ('T'-'A'): m = 10;break;	  case (('N'-'A') * 1024) + (('O'-'A') * 32) + ('V'-'A'): m = 11;break;	  case (('D'-'A') * 1024) + (('E'-'A') * 32) + ('C'-'A'): m = 12;break;	  default: return NIL;	  }	  if ((*++(*arg) == '-') && isdigit (*++(*arg))) {	    y = 0;		/* init year */	    do {	      y *= 10;		/* add this number */	      y += *(*arg)++ - '0';	    }	    while (isdigit (**arg));				/* minimal validity check of date */	    if (d < 1 || d > 31 || m < 1 || m > 12 || y < 0) return NIL; 				/* Tenex/ARPAnet began in 1969 */	    if (y 

⌨️ 快捷键说明

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