Example #1
0
/* PUBLIC						HTAA_parseArgList()
 *		PARSE AN ARGUMENT LIST GIVEN IN A HEADER FIELD
 * ON ENTRY:
 *	str	is a comma-separated list:
 *
 *			item, item, item
 *		where
 *			item ::= value
 *			       | name=value
 *			       | name="value"
 *
 *		Leading and trailing whitespace is ignored
 *		everywhere except inside quotes, so the following
 *		examples are equal:
 *
 *			name=value,foo=bar
 *			 name="value",foo="bar"
 *			  name = value ,  foo = bar
 *			   name = "value" ,  foo = "bar"
 *
 * ON EXIT:
 *	returns a list of name-value pairs (actually HTAssocList*).
 *		For items with no name, just value, the name is
 *		the number of order number of that item. E.g.
 *		"1" for the first, etc.
 */
HTAssocList *HTAA_parseArgList(char *str)
{
    HTAssocList *assoc_list = HTAssocList_new();
    char *cur = NULL;
    char *name = NULL;
    int n = 0;

    if (!str)
	return assoc_list;

    while (*str) {
	SKIPWS(str);		/* Skip leading whitespace */
	cur = str;
	n++;

	while (*cur && *cur != '=' && *cur != ',')
	    cur++;		/* Find end of name (or lonely value without a name) */
	KILLWS(cur);		/* Kill trailing whitespace */

	if (*cur == '=') {	/* Name followed by a value */
	    *(cur++) = '\0';	/* Terminate name */
	    StrAllocCopy(name, str);
	    SKIPWS(cur);	/* Skip WS leading the value */
	    str = cur;
	    if (*str == '"') {	/* Quoted value */
		str++;
		cur = str;
		while (*cur && *cur != '"')
		    cur++;
		if (*cur == '"')
		    *(cur++) = '\0';	/* Terminate value */
		/* else it is lacking terminating quote */
		SKIPWS(cur);	/* Skip WS leading comma */
		if (*cur == ',')
		    cur++;	/* Skip separating colon */
	    } else {		/* Unquoted value */
		while (*cur && *cur != ',')
		    cur++;
		KILLWS(cur);	/* Kill trailing whitespace */
		if (*cur == ',')
		    *(cur++) = '\0';
		/* else *cur already NULL */
	    }
	} else {		/* No name, just a value */
	    if (*cur == ',')
		*(cur++) = '\0';	/* Terminate value */
	    /* else last value on line (already terminated by NULL) */
	    HTSprintf0(&name, "%d", n);		/* Item order number for name */
	}
	HTAssocList_add(assoc_list, name, str);
	str = cur;
    }				/* while *str */

    FREE(name);
    return assoc_list;
}
Example #2
0
static ZZJSON *parse_value(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL;
    int c;

    SKIPWS();
    c = GETC();
    UNGETC(c);
    switch (c) {
        case '"':   retval = parse_string2(config); break;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '-':
                    retval = parse_number(config); break;
        case '{':   retval = parse_object(config); break;
        case '[':   retval = parse_array(config); break;
        case 't':   retval = parse_true(config); break;
        case 'f':   retval = parse_false(config); break;
        case 'n':   retval = parse_null(config); break;
    }

    if (!retval) {
        ERROR("value: invalid value");
        return retval;
    }

    return retval;
}
Example #3
0
static const char *
parse_mailboxdomain (const char *s, const char *nonspecial,
		     char *mailbox, size_t *mailboxlen, size_t mailboxmax,
		     char *comment, size_t *commentlen, size_t commentmax)
{
  const char *ps;

  while (*s)
  {
    SKIPWS (s);
    if (strchr (nonspecial, *s) == NULL && is_special (*s))
      return s;

    if (*s == '(')
    {
      if (*commentlen && *commentlen < commentmax)
	comment[(*commentlen)++] = ' ';
      ps = next_token (s, comment, commentlen, commentmax);
    }
    else
      ps = next_token (s, mailbox, mailboxlen, mailboxmax);
    if (!ps)
      return NULL;
    s = ps;
  }

  return s;
}
Example #4
0
/* Parse CAPA output */
static int fetch_capa (char *line, void *data)
{
  POP_DATA *pop_data = (POP_DATA *)data;
  char *c;

  if (!ascii_strncasecmp (line, "SASL", 4))
  {
    FREE (&pop_data->auth_list);
    c = line + 4;
    SKIPWS (c);
    pop_data->auth_list = safe_strdup (c);
  }

  else if (!ascii_strncasecmp (line, "STLS", 4))
    pop_data->cmd_stls = 1;

  else if (!ascii_strncasecmp (line, "USER", 4))
    pop_data->cmd_user = 1;

  else if (!ascii_strncasecmp (line, "UIDL", 4))
    pop_data->cmd_uidl = 1;

  else if (!ascii_strncasecmp (line, "TOP", 3))
    pop_data->cmd_top = 1;

  return 0;
}
Example #5
0
static const char *next_word (const char *s)
{
  while (*s && !ISSPACE (*s))
    s++;
  SKIPWS (s);
  return s;
}
Example #6
0
void
__find(char *in, struct __Token *min, struct __Token *max)
{
	char *it = in;
	char *next = it;
	int id = 0;


	memset(min, 0, sizeof(struct __Token));
	memset(max, 0, sizeof(struct __Token));

	SKIPWS(it);
	while (*it != 0) {
		if (iswspace((int)(*it))) {
			int len = it - next;
			if (min->len == 0) {
				min->len = len;
				min->loc = id - len;

				max->len = len;
				max->loc = id - len;
			} else {
				if (len > max->len) {
					max->len = len;
					max->loc = id - len;
				}
				if (len < min->len) {
					min->len = len;
					min->loc = id - len;
				}
			}
			SKIPWS(it);
			next = it;
		}
		++it;
		++id;
	}
}
Example #7
0
ZZJSON *zzjson_parse(ZZJSON_CONFIG *config) {
    ZZJSON *retval;
    int c;

    SKIPWS();   
    c = GETC();
    UNGETC(c);
    if (c == '[')       retval = parse_array(config);
    else if (c == '{')  retval = parse_object(config);
    else                { ERROR("expected '[' or '{'"); return NULL; }

    if (!retval) return NULL;

    SKIPWS();
    c = GETC();
    if (c >= 0 && !ALLOW_GARBAGE_AT_END) {
        ERROR("parse: garbage at end of file");
        zzjson_free(config, retval);
        return NULL;
    }

    return retval;
}
Example #8
0
struct userdefs *
getusrdef(char *usertype)
{
	char instr[512], *ptr;
	const parsent_t *pe;

	if (is_role(usertype)) {
		if ((defptr = fopen(DEFROLEFILE, "r")) == NULL) {
			defaults.defshell = DEFROLESHL;
			defaults.defprof = DEFROLEPROF;
			return (&defaults);
		}
	} else {
		if ((defptr = fopen(DEFFILE, "r")) == NULL)
			return (&defaults);
	}

	while (fgets(instr, sizeof (instr), defptr) != NULL) {
		ptr = instr;

		SKIPWS(ptr);

		if (*ptr == '#')
			continue;

		pe = scan(&ptr);

		if (pe != NULL) {
			switch (pe->type) {
			case INT:
				FIELD(&defaults, pe, int) =
					(int)strtol(ptr, NULL, 10);
				break;
			case PROJID:
				FIELD(&defaults, pe, projid_t) =
					(projid_t)strtol(ptr, NULL, 10);
				break;
			case STR:
				FIELD(&defaults, pe, char *) = dup_to_nl(ptr);
				break;
			}
		}
	}

	(void) fclose(defptr);

	return (&defaults);
}
Example #9
0
static const char *
parse_route_addr (const char *s,
		  char *comment, size_t *commentlen, size_t commentmax,
		  ADDRESS *addr)
{
  char token[STRING];
  size_t tokenlen = 0;

  SKIPWS (s);

  /* find the end of the route */
  if (*s == '@')
  {
    while (s && *s == '@')
    {
      if (tokenlen < sizeof (token) - 1)
	token[tokenlen++] = '@';
      s = parse_mailboxdomain (s + 1, ".\\[](", token,
			       &tokenlen, sizeof (token) - 1,
			       comment, commentlen, commentmax);
    }
    if (!s || *s != ':')
    {
      RFC822Error = ERR_BAD_ROUTE;
      return NULL; /* invalid route */
    }

    if (tokenlen < sizeof (token) - 1)
      token[tokenlen++] = ':';
    s++;
  }

  if ((s = parse_address (s, token, &tokenlen, sizeof (token) - 1, comment, commentlen, commentmax, addr)) == NULL)
    return NULL;

  if (*s != '>' || !addr->mailbox)
  {
    RFC822Error = ERR_BAD_ROUTE_ADDR;
    return NULL;
  }

  s++;
  return s;
}
Example #10
0
/* Copy error message to err_msg buffer */
void pop_error (POP_DATA *pop_data, char *msg)
{
  char *t, *c, *c2;

  t = strchr (pop_data->err_msg, '\0');
  c = msg;

  if (!mutt_strncmp (msg, "-ERR ", 5))
  {
    c2 = msg + 5;
    SKIPWS (c2);

    if (*c2)
      c = c2;
  }

  strfcpy (t, c, sizeof (pop_data->err_msg) - strlen (pop_data->err_msg));
  mutt_remove_trailing_ws (pop_data->err_msg);
}
Example #11
0
LPCSTR parse_route_addr( LPCSTR s,
             LPSTR comment, size_t *commentlen, size_t commentmax,
             PPerson addr )
{
  char token[128];
  size_t tokenlen = 0;

  SKIPWS (s);

  /* find the end of the route */
  if (*s == '@')
  {
    while (s && *s == '@')
    {
      if (tokenlen < sizeof (token) - 1)
        token[tokenlen++] = '@';
      s = parse_mailboxdomain (s + 1, ",.\\[](", token,
        &tokenlen, sizeof (token) - 1,
        comment, commentlen, commentmax);
    }
    if (!s || *s != ':')
    {
//      RFC822Error = ERR_BAD_ROUTE;
      return NULL; /* invalid route */
    }

    if (tokenlen < sizeof (token) - 1)
      token[tokenlen++] = ':';
    s++;
  }

  if ((s = parse_address (s, token, &tokenlen, sizeof (token) - 1, comment, commentlen, commentmax, addr)) == NULL)
    return NULL;

  if ( *s != '>' || addr->Addr.IsEmpty() )
  {
//    RFC822Error = ERR_BAD_ROUTE_ADDR;
    return NULL;
  }

  s ++;
  return s;
}
Example #12
0
/* imap_next_word: return index into string where next IMAP word begins */
char *imap_next_word (char *s)
{
  int quoted = 0;

  while (*s) {
    if (*s == '\\') {
      s++;
      if (*s)
        s++;
      continue;
    }
    if (*s == '\"')
      quoted = quoted ? 0 : 1;
    if (!quoted && ISSPACE (*s))
      break;
    s++;
  }

  SKIPWS (s);
  return s;
}
Example #13
0
/* NUL terminates a rfc 1524 field,
 * returns start of next field or NULL */
static char *get_field (char *s)
{
  char *ch;

  if (!s)
    return NULL;

  while ((ch = strpbrk (s, ";\\")) != NULL) {
    if (*ch == '\\') {
      s = ch + 1;
      if (*s)
        s++;
    }
    else {
      *ch++ = 0;
      SKIPWS (ch);
      break;
    }
  }
  str_skip_trailws (s);
  return ch;
}
Example #14
0
/**
 * mutt_parse_icommand - Parse an informational command
 * @param line Command to execute
 * @param err  Buffer for error messages
 * @retval #MUTT_CMD_SUCCESS Success
 * @retval #MUTT_CMD_ERROR   Error (no message): command not found
 * @retval #MUTT_CMD_ERROR   Error with message: command failed
 * @retval #MUTT_CMD_WARNING Warning with message: command failed
 */
enum CommandResult mutt_parse_icommand(/* const */ char *line, struct Buffer *err)
{
  if (!line || !*line || !err)
    return MUTT_CMD_ERROR;

  enum CommandResult rc = MUTT_CMD_ERROR;

  struct Buffer expn, token;

  mutt_buffer_init(&expn);
  mutt_buffer_init(&token);

  expn.data = expn.dptr = line;
  expn.dsize = mutt_str_strlen(line);

  mutt_buffer_reset(err);

  SKIPWS(expn.dptr);
  while (*expn.dptr)
  {
    mutt_extract_token(&token, &expn, 0);
    for (size_t i = 0; ICommandList[i].name; i++)
    {
      if (mutt_str_strcmp(token.data, ICommandList[i].name) != 0)
        continue;

      rc = ICommandList[i].func(&token, &expn, ICommandList[i].data, err);
      if (rc != 0)
        goto finish;

      break; /* Continue with next command */
    }
  }

finish:
  if (expn.destroy)
    FREE(&expn.data);
  return rc;
}
Example #15
0
/* args:
 *      ctx	Context info, used when recalling a message to which
 *              we reply.
 *	hdr	envelope/attachment info for recalled message
 *	cur	if message was a reply, `cur' is set to the message which
 *		`hdr' is in reply to
 *	fcc	fcc for the recalled message
 *	fcclen	max length of fcc
 *
 * return vals:
 *	-1		error/no messages
 *	0		normal exit
 *	SENDREPLY	recalled message is a reply
 */
int mutt_get_postponed (CONTEXT * ctx, HEADER * hdr, HEADER ** cur, char *fcc,
                        size_t fcclen)
{
  HEADER *h;
  int code = SENDPOSTPONED;
  LIST *tmp;
  LIST *last = NULL;
  LIST *next;
  char *p;
  int opt_delete;

  if (!Postponed)
    return (-1);

  if ((PostContext = mx_open_mailbox (Postponed, M_NOSORT, NULL)) == NULL) {
    PostCount = 0;
    mutt_error _("No postponed messages.");

    return (-1);
  }

  if (!PostContext->msgcount) {
    PostCount = 0;
    mx_close_mailbox (PostContext, NULL);
    mem_free (&PostContext);
    mutt_error _("No postponed messages.");

    return (-1);
  }

  if (PostContext->msgcount == 1) {
    /* only one message, so just use that one. */
    h = PostContext->hdrs[0];
  }
  else if ((h = select_msg ()) == NULL) {
    mx_close_mailbox (PostContext, NULL);
    mem_free (&PostContext);
    return (-1);
  }

  if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0) {
    mx_fastclose_mailbox (PostContext);
    mem_free (&PostContext);
    return (-1);
  }

  /* finished with this message, so delete it. */
  mutt_set_flag (PostContext, h, M_DELETE, 1);

  /* and consider it saved, so that it won't be moved to the trash folder */
  mutt_set_flag (PostContext, h, M_APPENDED, 1);

  /* update the count for the status display */
  PostCount = PostContext->msgcount - PostContext->deleted;

  /* avoid the "purge deleted messages" prompt */
  opt_delete = quadoption (OPT_DELETE);
  set_quadoption (OPT_DELETE, M_YES);
  mx_close_mailbox (PostContext, NULL);
  set_quadoption (OPT_DELETE, opt_delete);

  mem_free (&PostContext);

  for (tmp = hdr->env->userhdrs; tmp;) {
    if (ascii_strncasecmp ("X-Mutt-References:", tmp->data, 18) == 0) {
      if (ctx) {
        /* if a mailbox is currently open, look to see if the orignal message
           the user attempted to reply to is in this mailbox */
        p = tmp->data + 18;
        SKIPWS (p);
        if (!ctx->id_hash)
          ctx->id_hash = mutt_make_id_hash (ctx);
        *cur = hash_find (ctx->id_hash, p);
      }

      /* Remove the X-Mutt-References: header field. */
      next = tmp->next;
      if (last)
        last->next = tmp->next;
      else
        hdr->env->userhdrs = tmp->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
      tmp = next;
      if (*cur)
        code |= SENDREPLY;
    }
    else if (ascii_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0) {
      p = tmp->data + 11;
      SKIPWS (p);
      strfcpy (fcc, p, fcclen);
      mutt_pretty_mailbox (fcc);

      /* remove the X-Mutt-Fcc: header field */
      next = tmp->next;
      if (last)
        last->next = tmp->next;
      else
        hdr->env->userhdrs = tmp->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
      tmp = next;
    }
    else if ((WithCrypto & APPLICATION_PGP)
             && (str_ncmp ("Pgp:", tmp->data, 4) == 0       /* this is generated
                                                                 * by old mutt versions
                                                                 */
                 || str_ncmp ("X-Mutt-PGP:", tmp->data, 11) == 0)) {
      hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1);
      hdr->security |= APPLICATION_PGP;

      /* remove the pgp field */
      next = tmp->next;
      if (last)
        last->next = tmp->next;
      else
        hdr->env->userhdrs = tmp->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
      tmp = next;
    }
    else if ((WithCrypto & APPLICATION_SMIME)
             && str_ncmp ("X-Mutt-SMIME:", tmp->data, 13) == 0) {
      hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1);
      hdr->security |= APPLICATION_SMIME;

      /* remove the smime field */
      next = tmp->next;
      if (last)
        last->next = tmp->next;
      else
        hdr->env->userhdrs = tmp->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
      tmp = next;
    }

#ifdef MIXMASTER
    else if (str_ncmp ("X-Mutt-Mix:", tmp->data, 11) == 0) {
      char *t;

      mutt_free_list (&hdr->chain);

      t = strtok (tmp->data + 11, " \t\n");
      while (t) {
        hdr->chain = mutt_add_list (hdr->chain, t);
        t = strtok (NULL, " \t\n");
      }

      next = tmp->next;
      if (last)
        last->next = tmp->next;
      else
        hdr->env->userhdrs = tmp->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
      tmp = next;
    }
#endif

    else {
      last = tmp;
      tmp = tmp->next;
    }
  }
  return (code);
}
Example #16
0
int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
{
  IMAP_DATA* idata;
  FILE *fp;
  char buf[LONG_STRING];
  char mbox[LONG_STRING];
  char mailbox[LONG_STRING];
  char internaldate[IMAP_DATELEN];
  char imap_flags[SHORT_STRING];
  size_t len;
  progress_t progressbar;
  size_t sent;
  int c, last;
  IMAP_MBOX mx;
  int rc;

  idata = (IMAP_DATA*) ctx->data;

  if (imap_parse_path (ctx->path, &mx))
    return -1;

  imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox));
  if (!*mailbox)
    strfcpy (mailbox, "INBOX", sizeof (mailbox));

  if ((fp = fopen (msg->path, "r")) == NULL)
  {
    mutt_perror (msg->path);
    goto fail;
  }

  /* currently we set the \Seen flag on all messages, but probably we
   * should scan the message Status header for flag info. Since we're
   * already rereading the whole file for length it isn't any more
   * expensive (it'd be nice if we had the file size passed in already
   * by the code that writes the file, but that's a lot of changes.
   * Ideally we'd have a HEADER structure with flag info here... */
  for (last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
  {
    if(c == '\n' && last != '\r')
      len++;

    len++;
  }
  rewind (fp);

  mutt_progress_init (&progressbar, _("Uploading message..."),
		      MUTT_PROGRESS_SIZE, NetInc, len);

  imap_munge_mbox_name (idata, mbox, sizeof (mbox), mailbox);
  imap_make_date (internaldate, msg->received);

  imap_flags[0] = imap_flags[1] = 0;
  if (msg->flags.read)
    safe_strcat (imap_flags, sizeof (imap_flags), " \\Seen");
  if (msg->flags.replied)
    safe_strcat (imap_flags, sizeof (imap_flags), " \\Answered");
  if (msg->flags.flagged)
    safe_strcat (imap_flags, sizeof (imap_flags), " \\Flagged");
  if (msg->flags.draft)
    safe_strcat (imap_flags, sizeof (imap_flags), " \\Draft");

  snprintf (buf, sizeof (buf), "APPEND %s (%s) \"%s\" {%lu}", mbox,
            imap_flags + 1,
	    internaldate,
	    (unsigned long) len);

  imap_cmd_start (idata, buf);

  do
    rc = imap_cmd_step (idata);
  while (rc == IMAP_CMD_CONTINUE);

  if (rc != IMAP_CMD_RESPOND)
  {
    char *pc;

    dprint (1, (debugfile, "imap_append_message(): command failed: %s\n",
		idata->buf));

    pc = idata->buf + SEQLEN;
    SKIPWS (pc);
    pc = imap_next_word (pc);
    mutt_error ("%s", pc);
    mutt_sleep (1);
    safe_fclose (&fp);
    goto fail;
  }

  for (last = EOF, sent = len = 0; (c = fgetc(fp)) != EOF; last = c)
  {
    if (c == '\n' && last != '\r')
      buf[len++] = '\r';

    buf[len++] = c;

    if (len > sizeof(buf) - 3)
    {
      sent += len;
      flush_buffer(buf, &len, idata->conn);
      mutt_progress_update (&progressbar, sent, -1);
    }
  }

  if (len)
    flush_buffer(buf, &len, idata->conn);

  mutt_socket_write (idata->conn, "\r\n");
  safe_fclose (&fp);

  do
    rc = imap_cmd_step (idata);
  while (rc == IMAP_CMD_CONTINUE);

  if (!imap_code (idata->buf))
  {
    char *pc;

    dprint (1, (debugfile, "imap_append_message(): command failed: %s\n",
		idata->buf));
    pc = idata->buf + SEQLEN;
    SKIPWS (pc);
    pc = imap_next_word (pc);
    mutt_error ("%s", pc);
    mutt_sleep (1);
    goto fail;
  }

  FREE (&mx.mbox);
  return 0;

 fail:
  FREE (&mx.mbox);
  return -1;
}
Example #17
0
int mutt_parse_crypt_hdr (char *p, int set_signas)
{
  int pgp = 0;
  char pgp_sign_as[LONG_STRING] = "\0", *q;
  char smime_cryptalg[LONG_STRING] = "\0";

  if (!WithCrypto)
    return 0;

  SKIPWS (p);
  for (; *p; p++) {

    switch (*p) {
    case 'e':
    case 'E':
      pgp |= ENCRYPT;
      break;

    case 's':
    case 'S':
      pgp |= SIGN;
      q = pgp_sign_as;

      if (*(p + 1) == '<') {
        for (p += 2;
             *p && *p != '>' && q < pgp_sign_as + sizeof (pgp_sign_as) - 1;
             *q++ = *p++);

        if (*p != '>') {
          mutt_error _("Illegal PGP header");

          return 0;
        }
      }

      *q = '\0';
      break;

      /* This used to be the micalg parameter.
       * 
       * It's no longer needed, so we just skip the parameter in order
       * to be able to recall old messages.
       */
    case 'm':
    case 'M':
      if (*(p + 1) == '<') {
        for (p += 2; *p && *p != '>'; p++);
        if (*p != '>') {
          mutt_error _("Illegal PGP header");

          return 0;
        }
      }

      break;


    case 'c':
    case 'C':
      q = smime_cryptalg;

      if (*(p + 1) == '<') {
        for (p += 2;
             *p && *p != '>'
             && q < smime_cryptalg + sizeof (smime_cryptalg) - 1;
             *q++ = *p++);

        if (*p != '>') {
          mutt_error _("Illegal S/MIME header");

          return 0;
        }
      }

      *q = '\0';
      break;

    case 'i':
    case 'I':
      pgp |= INLINE;
      break;

    default:
      mutt_error _("Illegal PGP header");
      return 0;
    }

  }

  /* the cryptalg field must not be empty */
  if ((WithCrypto & APPLICATION_SMIME) && *smime_cryptalg)
    str_replace (&SmimeCryptAlg, smime_cryptalg);

  if ((WithCrypto & APPLICATION_PGP) && (set_signas || *pgp_sign_as))
    str_replace (&PgpSignAs, pgp_sign_as);

  return pgp;
}
Example #18
0
char *mutt_skip_whitespace (char *p)
{
  SKIPWS (p);
  return p;
}
Example #19
0
ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
{
  const char *begin, *ps;
  char comment[STRING], phrase[STRING];
  size_t phraselen = 0, commentlen = 0;
  ADDRESS *cur, *last = NULL;
  
  RFC822Error = 0;

  last = top;
  while (last && last->next)
    last = last->next;

  SKIPWS (s);
  begin = s;
  while (*s)
  {
    if (*s == ',')
    {
      if (phraselen)
      {
	phrase[phraselen] = 0;
	add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
      }
      else if (commentlen && last && !last->personal)
      {
	comment[commentlen] = 0;
	last->personal = safe_strdup (comment);
      }

#ifdef EXACT_ADDRESS
      if (last && !last->val)
	last->val = mutt_substrdup (begin, s);
#endif
      commentlen = 0;
      phraselen = 0;
      s++;
      begin = s;
      SKIPWS (begin);
    }
    else if (*s == '(')
    {
      if (commentlen && commentlen < sizeof (comment) - 1)
	comment[commentlen++] = ' ';
      if ((ps = next_token (s, comment, &commentlen, sizeof (comment) - 1)) == NULL)
      {
	rfc822_free_address (&top);
	return NULL;
      }
      s = ps;
    }
    else if (*s == ':')
    {
      cur = rfc822_new_address ();
      phrase[phraselen] = 0;
      cur->mailbox = safe_strdup (phrase);
      cur->group = 1;

      if (last)
	last->next = cur;
      else
	top = cur;
      last = cur;

#ifdef EXACT_ADDRESS
      last->val = mutt_substrdup (begin, s);
#endif

      phraselen = 0;
      commentlen = 0;
      s++;
      begin = s;
      SKIPWS (begin);
    }
    else if (*s == ';')
    {
      if (phraselen)
      {
	phrase[phraselen] = 0;
	add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
      }
      else if (commentlen && !last->personal)
      {
	comment[commentlen] = 0;
	last->personal = safe_strdup (comment);
      }
#ifdef EXACT_ADDRESS
      if (last && !last->val)
	last->val = mutt_substrdup (begin, s);
#endif

      /* add group terminator */
      cur = rfc822_new_address ();
      if (last)
      {
	last->next = cur;
	last = cur;
      }

      phraselen = 0;
      commentlen = 0;
      s++;
      begin = s;
      SKIPWS (begin);
    }
    else if (*s == '<')
    {
      phrase[phraselen] = 0;
      cur = rfc822_new_address ();
      if (phraselen)
      {
	if (cur->personal)
	  FREE (&cur->personal);
	/* if we get something like "Michael R. Elkins" remove the quotes */
	rfc822_dequote_comment (phrase);
	cur->personal = safe_strdup (phrase);
      }
      if ((ps = parse_route_addr (s + 1, comment, &commentlen, sizeof (comment) - 1, cur)) == NULL)
      {
	rfc822_free_address (&top);
	rfc822_free_address (&cur);
	return NULL;
      }

      if (last)
	last->next = cur;
      else
	top = cur;
      last = cur;

      phraselen = 0;
      commentlen = 0;
      s = ps;
    }
    else
    {
      if (phraselen && phraselen < sizeof (phrase) - 1)
	phrase[phraselen++] = ' ';
      if ((ps = next_token (s, phrase, &phraselen, sizeof (phrase) - 1)) == NULL)
      {
	rfc822_free_address (&top);
	return NULL;
      }
      s = ps;
    }
    SKIPWS (s);
  }
  
  if (phraselen)
  {
    phrase[phraselen] = 0;
    comment[commentlen] = 0;
    add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
  }
  else if (commentlen && last && !last->personal)
  {
    comment[commentlen] = 0;
    last->personal = safe_strdup (comment);
  }
#ifdef EXACT_ADDRESS
  if (last)
    last->val = mutt_substrdup (begin, s);
#endif

  return top;
}
Example #20
0
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle)
{
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if (!strncmp(s, "#include ", 9) && include_handle != INCLUDE_IGNORE)
    {
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else
      {
        return nerr_raise (NERR_MAX_RECURSION,
                                     "[%d]: Too many recursion levels.",
                                     *lineno
                                     );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *(unsigned char*)s > 127)) s++;
      SKIPWS(s);

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	value = hdf_get_value(hdf->top, value, "");
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
            void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
            {
              free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
            }
            m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  return STATUS_OK;
}
Example #21
0
PPerson rfc822_parse_adrlist( PPerson Top, LPCSTR s )
{
  LPCSTR begin;
  LPCSTR ps;
  char comment[128], phrase[128];
  size_t phraselen = 0, commentlen = 0;

  PPerson Cur;
  PPerson Last = Top;

  while ( Last && Last->m_Next ) Last = Last->m_Next;

  SKIPWS( s );

  begin = s;
  while ( *s )
  {
    if ( *s == ',' )
    {
      if ( phraselen )
      {
        terminate_buffer( phrase, phraselen );
        add_addrspec( &Top, &Last, phrase, comment, &commentlen, sizeof( comment ) - 1 );
      }
      else if ( commentlen && Last && Last->Name.IsEmpty() )
      {
        terminate_buffer( comment, commentlen );
        Last->Name = comment;
      }

#ifdef EXACT_ADDRESS
      if ( Last && Last->val == NULL )
        Last->val = mutt_substrdup( begin, s );
#endif
      commentlen = 0;
      phraselen  = 0;
      s ++;
      begin = s;
      SKIPWS( begin );
    }
    else if ( *s == '(' )
    {
      if ( commentlen && commentlen < sizeof( comment ) - 1 )
        comment[ commentlen++ ] = ' ';
      if ( ( ps = next_token( s, comment, &commentlen, sizeof (comment) - 1)) == NULL )
      {
        delete Top;
        Top = NULL;
        return NULL;
      }
      s = ps;
    }
    else if ( *s == ':' )
    {
      terminate_buffer( phrase, phraselen );
      Cur = create CPerson;
      Cur->Addr = phrase;
      //Cur->group = 1;

      if ( Last )
        Last->m_Next = Cur;
      else
        Top = Cur;

      Last = Cur;

#ifdef EXACT_ADDRESS
      last->val = mutt_substrdup (begin, s);
#endif

      phraselen  = 0;
      commentlen = 0;
      s ++;
      begin = s;
      SKIPWS( begin );
    }
    else if ( *s == ';' )
    {
      if ( phraselen )
      {
        terminate_buffer (phrase, phraselen);
        add_addrspec( &Top, &Last, phrase, comment, &commentlen, sizeof( comment ) - 1 );
      }
      else if (commentlen && Last && Last->Name.IsEmpty() )
      {
        terminate_buffer (comment, commentlen);
        Last->Name = comment;
      }
#ifdef EXACT_ADDRESS
      if (last && !last->val)
        last->val = mutt_substrdup (begin, s);
#endif

      /* add group terminator */
      Cur = create CPerson;
      if ( Last )
      {
        Last->m_Next = Cur;
        Last = Cur;
      }

      phraselen  = 0;
      commentlen = 0;
      s ++;
      begin = s;
      SKIPWS( begin );
    }
    else if ( *s == '<' )
    {
      terminate_buffer( phrase, phraselen );
      Cur = create CPerson;
      if ( phraselen )
      {
        FarSF::Unquote( phrase );
        Cur->Name = phrase;
      }
      if ( ( ps = parse_route_addr( s + 1, comment, &commentlen, sizeof( comment ) - 1, Cur ) ) == NULL )
      {
        delete Top;
        delete Cur;
        Top = NULL;
        Cur = NULL;
        return NULL;
      }

      if ( Last )
        Last->m_Next = Cur;
      else
        Top = Cur;
      Last = Cur;

      phraselen  = 0;
      commentlen = 0;
      s = ps;
    }
    else
    {
      if ( phraselen && phraselen < sizeof( phrase ) - 1 && *s != '.' )
        phrase[phraselen++] = ' ';
      if ( ( ps = next_token( s, phrase, &phraselen, sizeof( phrase ) - 1 ) ) == NULL )
      {
        delete Top;
        Top = NULL;
        return NULL;
      }
      s = ps;
    }
    SKIPWS (s);
  }

  if (phraselen)
  {
    terminate_buffer (phrase, phraselen);
    terminate_buffer (comment, commentlen);
    add_addrspec( &Top, &Last, phrase, comment, &commentlen, sizeof( comment ) - 1 );
  }
  else if ( commentlen && Last && Last->Name.IsEmpty() )
  {
    terminate_buffer( comment, commentlen );
    Last->Name = comment;
  }
#ifdef EXACT_ADDRESS
  if ( Last )
    Last->val = mutt_substrdup( begin, s );
#endif

  return Top;
}
Example #22
0
/* After calling,
 * - b->data points to the found token, or NULL is end of parsing
 * - b->ptr  points to the begining of next token
 *
 * If the TOKEN_ALLOC option is used, the original string is not mangled
 * and memory is allocated for the token.
 */
static char *
get_token(buffer *b, int options)
{
	char quote = 0, c;
	char *end = NULL;

	assert(b);

	SKIPWS(b->ptr);
	if(*b->ptr && strchr("\"'", *b->ptr))
		quote = *(b->ptr++);
	b->data = b->ptr;

	while(1) {
		if(!(c = *b->ptr)) {
			end = b->ptr;
			break;
		}

		if(!quote && (
				ISSPACE(c) ||
				((options & TOKEN_EQUAL) && (c == '=')) ||
				((options & TOKEN_COMMA) && (c == ',')))
				) {
			end = b->ptr;
			break;
		} else if(c == quote) {
			quote = 0;
			end = b->ptr++;
			break;
		}

		b->ptr++;
	}

	if(quote)
		return _("quote mismatch");

	if(options & (TOKEN_EQUAL | TOKEN_COMMA))
		SKIPWS(b->ptr); /* whitespaces can precede the sign */

	if((options & TOKEN_EQUAL) && (*b->ptr != '='))
		return _("no assignment character found");

	if((options & TOKEN_COMMA) && *b->ptr && (*b->ptr != ','))
		return _("error in comma separated list");

	if(b->ptr == b->data) {
		b->data = NULL;
		return NULL; /* no error, just end of parsing */
	}

	if(options & TOKEN_ALLOC) /* freeing is the caller's responsibility */
		b->data = xstrndup(b->data, end - b->data);
	else
		*end = 0;

	b->ptr++; /* advance to next token */
	SKIPWS(b->ptr);

	return NULL;
}
Example #23
0
/* attributes are of the form [key1, key2, key3=value, key4="repr"] */
static NEOERR* parse_attr(char **str, HDF_ATTR **attr)
{
  NEOERR *err = STATUS_OK;
  char *s = *str;
  char *k, *v;
  int k_l, v_l;
  STRING buf;
  char c;
  HDF_ATTR *ha, *hal = NULL;

  *attr = NULL;

  string_init(&buf);
  while (*s && *s != ']')
  {
    k = s;
    k_l = 0;
    v = NULL;
    v_l = 0;
    while (*s && isalnum(*s)) s++;
    k_l = s-k;
    if (*s == '\0' || k_l == 0)
    {
      _dealloc_hdf_attr(attr);
      return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
    }
    SKIPWS(s);
    if (*s == '=')
    {
      s++;
      SKIPWS(s);
      if (*s == '"')
      {
	s++;
	while (*s && *s != '"')
	{
	  if (*s == '\\')
	  {
	    if (isdigit(*(s+1)))
	    {
	      s++;
	      c = *s - '0';
	      if (isdigit(*(s+1)))
	      {
		s++;
		c = (c * 8) + (*s - '0');
		if (isdigit(*(s+1)))
		{
		  s++;
		  c = (c * 8) + (*s - '0');
		}
	      }
	    }
	    else
	    {
	      s++;
	      if (*s == 'n') c = '\n';
	      else if (*s == 't') c = '\t';
	      else if (*s == 'r') c = '\r';
	      else c = *s;
	    }
	    err = string_append_char(&buf, c);
	  }
	  else
	  {
	    err = string_append_char(&buf, *s);
	  }
	  if (err)
	  {
	    string_clear(&buf);
	    _dealloc_hdf_attr(attr);
	    return nerr_pass(err);
	  }
	  s++;
	}
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  string_clear(&buf);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
	s++;
	v = buf.buf;
        v_l = buf.len;
      }
      else
      {
	v = s;
	while (*s && *s != ' ' && *s != ',' && *s != ']') s++;
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
        v_l = s-v;
      }
    }
    else
    {
      v = "1";
    }
    ha = (HDF_ATTR*) calloc (1, sizeof(HDF_ATTR));
    if (ha == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (*attr == NULL) *attr = ha;
    ha->key = neos_strndup(k, k_l);
    if (v)
      ha->value = neos_strndup(v, v_l);
    else
      ha->value = strdup("");
    if (ha->key == NULL || ha->value == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (hal != NULL) hal->next = ha;
    hal = ha;
    string_clear(&buf);
    SKIPWS(s);
    if (*s == ',')
    {
      s++;
      SKIPWS(s);
    }
  }
  if (*s == '\0')
  {
    _dealloc_hdf_attr(attr);
    return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
  }
  *str = s+1;
  return STATUS_OK;
}
Example #24
0
static ZZJSON *parse_array(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL, **next = &retval;
    int c;

    SKIPWS();
    c = GETC();
    if (c != '[') {
        ERROR("array: expected '['");
        return NULL;
    }

    SKIPWS();
    c = GETC();
    while (c > 0 && c != ']') {
        ZZJSON *zzjson = NULL, *val = NULL;

        UNGETC(c);

        SKIPWS();
        val = parse_value(config);
        if (!val) {
            ERROR("array: value expected");
            goto errout;
        }

        SKIPWS();
        c = GETC();
        if (c != ',' && c != ']') {
            ERROR("array: expected ',' or ']'");
errout_with_val:
            zzjson_free(config, val);
            goto errout;
        }
        if (c == ',') {
            SKIPWS();
            c = GETC();
            if (c == ']' && !ALLOW_EXTRA_COMMA) {
                ERROR("array: expected value after ','");
                goto errout_with_val;
            }
        }
        UNGETC(c);

        zzjson = config->calloc(1, sizeof(ZZJSON));
        if (!zzjson) {
            MEMERROR();
            zzjson_free(config, val);
            goto errout_with_val;
        }
        zzjson->type            = ZZJSON_ARRAY;
        zzjson->value.array.val = val;
        *next = zzjson;
        next = &zzjson->next;

        c = GETC();
    }

    if (c != ']') {
        ERROR("array: expected ']'");
        goto errout;
    }

    if (!retval) {  /* empty array, [ ] */
        retval = config->calloc(1, sizeof(ZZJSON));
        if (!retval) {
            MEMERROR();
            return NULL;
        }
        retval->type = ZZJSON_ARRAY;
    }
            
    return retval;

errout:
    zzjson_free(config, retval);
    return NULL;
}
Example #25
0
int is_from (const char *s, char *path, size_t pathlen, time_t *tp)
{
  struct tm tm;
  int yr;

  if (path)
    *path = 0;

  if (mutt_strncmp ("From ", s, 5) != 0)
    return 0;

  s = next_word (s); /* skip over the From part. */
  if (!*s)
    return 0;

  dprint (3, (debugfile, "\nis_from(): parsing: %s", s));

  if (!is_day_name (s))
  {
    const char *p;
    size_t len;
    short q = 0;

    for (p = s; *p && (q || !ISSPACE (*p)); p++)
    {
      if (*p == '\\')
      {
	if (*++p == '\0') 
	  return 0;
      }
      else if (*p == '"')
      {
	q = !q;
      }
    }

    if (q || !*p) return 0;

    /* pipermail archives have the return_path obscured such as "me at mutt.org" */
    if (ascii_strncasecmp(p, " at ", 4) == 0)
    {
      p = strchr(p + 4, ' ');
      if (!p)
      {
	dprint (1, (debugfile, "is_from(): error parsing what appears to be a pipermail-style obscured return_path: %s\n", s));
	return 0;
      }
    }
    
    if (path)
    {
      len = (size_t) (p - s);
      if (len + 1 > pathlen)
	len = pathlen - 1;
      memcpy (path, s, len);
      path[len] = 0;
      dprint (3, (debugfile, "is_from(): got return path: %s\n", path));
    }
    
    s = p + 1;
    SKIPWS (s);
    if (!*s)
      return 0;

    if (!is_day_name (s))
    {
      dprint(1, (debugfile, "is_from():  expected weekday, got: %s\n", s));
      return 0;
    }
  }

  s = next_word (s);
  if (!*s) return 0;

  /* do a quick check to make sure that this isn't really the day of the week.
   * this could happen when receiving mail from a local user whose login name
   * is the same as a three-letter abbreviation of the day of the week.
   */
  if (is_day_name (s))
  {
    s = next_word (s);
    if (!*s) return 0;
  }

  /* now we should be on the month. */
  if ((tm.tm_mon = mutt_check_month (s)) < 0) return 0;

  /* day */
  s = next_word (s);
  if (!*s) return 0;
  if (sscanf (s, "%d", &tm.tm_mday) != 1) return 0;

  /* time */
  s = next_word (s);
  if (!*s) return 0;

  /* Accept either HH:MM or HH:MM:SS */
  if (sscanf (s, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 3);
  else if (sscanf (s, "%d:%d", &tm.tm_hour, &tm.tm_min) == 2)
    tm.tm_sec = 0;
  else
    return 0;

  s = next_word (s);
  if (!*s) return 0;

  /* timezone? */
  if (isalpha ((unsigned char) *s) || *s == '+' || *s == '-')
  {
    s = next_word (s);
    if (!*s) return 0;

    /*
     * some places have two timezone fields after the time, e.g.
     *      From [email protected] Wed Aug  2 00:39:12 MET DST 1995
     */
    if (isalpha ((unsigned char) *s))
    {
      s = next_word (s);
      if (!*s) return 0;
    }
  }

  /* year */
  if (sscanf (s, "%d", &yr) != 1) return 0;
  tm.tm_year = yr > 1900 ? yr - 1900 : (yr < 70 ? yr + 100 : yr);
  
  dprint (3,(debugfile, "is_from(): month=%d, day=%d, hr=%d, min=%d, sec=%d, yr=%d.\n",
	     tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year));

  tm.tm_isdst = -1;

  if (tp) *tp = mutt_mktime (&tm, 0);
  return 1;
}
Example #26
0
static ZZJSON *parse_object(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL;
    int c;
    ZZJSON **next = &retval;

    SKIPWS();
    c = GETC();
    if (c != '{') {
        ERROR("object: expected '{'");
        return NULL;
    }

    SKIPWS();
    c = GETC();
    while (c > 0 && c != '}') {
        ZZJSON *zzjson = NULL, *val = NULL;
        char *str;

        UNGETC(c);

        str = parse_string(config);
        if (!str) {
            ERROR("object: expected string");
errout_with_str:
            config->free(str);
            goto errout;
        }

        SKIPWS();
        c = GETC();
        if (c != ':') {
            ERROR("object: expected ':'");
            goto errout_with_str;
        }

        SKIPWS();
        val = parse_value(config);
        if (!val) {
            ERROR("object: value expected");
            goto errout_with_str;
        }

        SKIPWS();
        c = GETC();
        if (c != ',' && c != '}') {
            ERROR("object: expected ',' or '}'");
errout_with_str_and_val:
            zzjson_free(config, val);
            goto errout_with_str;
        }
        if (c == ',') {
            SKIPWS();
            c = GETC();
            if (c == '}' && !ALLOW_EXTRA_COMMA) {
                ERROR("object: expected pair after ','");
                goto errout_with_str_and_val;
            }
        }
        UNGETC(c);

        zzjson = config->calloc(1, sizeof(ZZJSON));
        if (!zzjson) {
            MEMERROR();
            goto errout_with_str_and_val;
        }
        zzjson->type                = ZZJSON_OBJECT;
        zzjson->value.object.label  = str;
        zzjson->value.object.val    = val;
        *next = zzjson;
        next = &zzjson->next;

        c = GETC();
    }

    if (c != '}') {
        ERROR("object: expected '}'");
        goto errout;
    }

    if (!retval) {  /* empty object, { } */
        retval = config->calloc(1, sizeof(ZZJSON));
        if (!retval) {
            MEMERROR();
            return NULL;
        }
        retval->type = ZZJSON_OBJECT;
    }
            
    return retval;

errout:
    zzjson_free(config, retval);
    return NULL;
}
void mutt_edit_headers (const char *editor,
			const char *body,
			HEADER *msg,
			char *fcc,
			size_t fcclen)
{
  char path[_POSIX_PATH_MAX];	/* tempfile used to edit headers + body */
  char buffer[LONG_STRING];
  char *p;
  FILE *ifp, *ofp;
  int i, keep;
  int in_reply_to = 0;	/* did we see the in-reply-to field ? */
  ENVELOPE *n;
  time_t mtime;
  struct stat st;
  LIST *cur, *last = NULL, *tmp;

  mutt_mktemp (path);
  if ((ofp = safe_fopen (path, "w")) == NULL)
  {
    mutt_perror (path);
    return;
  }

  mutt_write_rfc822_header (ofp, msg->env, NULL, 1, 0);
  fputc ('\n', ofp);	/* tie off the header. */

  /* now copy the body of the message. */
  if ((ifp = fopen (body, "r")) == NULL)
  {
    mutt_perror (body);
    return;
  }

  mutt_copy_stream (ifp, ofp);

  fclose (ifp);
  fclose (ofp);

  if (stat (path, &st) == -1)
  {
    mutt_perror (path);
    return;
  }

  mtime = st.st_mtime;
  mutt_edit_file (editor, path);
  stat (path, &st);
  if (mtime == st.st_mtime)
  {
    dprint (1, (debugfile, "ci_edit_headers(): temp file was not modified.\n"));
    /* the file has not changed! */
    mutt_unlink (path);
    return;
  }

  mutt_unlink (body);
  mutt_free_list (&msg->env->userhdrs);

  /* Read the temp file back in */
  if ((ifp = fopen (path, "r")) == NULL)
  {
    mutt_perror (path);
    return;
  }
  
  if ((ofp = safe_fopen (body, "w")) == NULL)
  {
    /* intentionally leak a possible temporary file here */
    fclose (ifp);
    mutt_perror (body);
    return;
  }
  
  n = mutt_read_rfc822_header (ifp, NULL, 1, 0);
  while ((i = fread (buffer, 1, sizeof (buffer), ifp)) > 0)
    fwrite (buffer, 1, i, ofp);
  fclose (ofp);
  fclose (ifp);
  mutt_unlink (path);

  /* restore old info. */
  n->references = msg->env->references;
  msg->env->references = NULL;
  mutt_free_envelope (&msg->env);
  msg->env = n;

  mutt_expand_aliases_env (msg->env);
  
  /* search through the user defined headers added to see if either a 
   * fcc: or attach-file: field was specified.  
   */

  cur = msg->env->userhdrs;
  while (cur)
  {
    keep = 1;

    /* keep track of whether or not we see the in-reply-to field.  if we did
     * not, remove the references: field later so that we can generate a new
     * message based upon this one.
     */
    if (mutt_strncasecmp ("in-reply-to. good thing you replied:", cur->data, 12) == 0)
      in_reply_to = 1;
    else if (fcc && mutt_strncasecmp ("fcc:", cur->data, 4) == 0)
    {
      p = cur->data + 4;
      SKIPWS (p);
      if (*p)
      {
	strfcpy (fcc, p, fcclen);
	mutt_pretty_mailbox (fcc);
      }
      keep = 0;
    }
    else if (mutt_strncasecmp ("attach file:", cur->data, 7) == 0)
    {
      BODY *body;
      BODY *parts;
      char *q;

      p = cur->data + 7;
      SKIPWS (p);
      if (*p)
      {
	if ((q = strpbrk (p, " \t")))
	{
	  mutt_substrcpy (path, p, q, sizeof (path));
	  SKIPWS (q);
	}
	else
	  strfcpy (path, p, sizeof (path));
	mutt_expand_path (path, sizeof (path));
	if ((body = mutt_make_file_attach (path)))
	{
	  body->description = safe_strdup (q);
	  for (parts = msg->content; parts->next; parts = parts->next) ;
	  parts->next = body;
	}
	else
	{
	  mutt_pretty_mailbox (path);
	  mutt_error (_("%s: unable to attach file. try again"), path);
	}
      }
      keep = 0;
    }



#ifdef HAVE_PGP
    else if (mutt_strncasecmp ("pgp:", cur->data, 4) == 0)
    {
      msg->pgp = mutt_parse_pgp_hdr (cur->data + 4, 0);
      keep = 0;
    }
#endif


    if (keep)
    {
      last = cur;
      cur = cur->next;
    }
    else
    {
      if (last)
	last->next = cur->next;
      else
	msg->env->userhdrs = cur->next;
      tmp = cur;
      cur = cur->next;
      tmp->next = NULL;
      mutt_free_list (&tmp);
    }
  }

  if (!in_reply_to)
    mutt_free_list (&msg->env->references);
}
Example #28
0
static ZZJSON *parse_number(ZZJSON_CONFIG *config) {
    ZZJSON *zzjson;
    unsigned long long ival = 0, expo = 0;
    double dval = 0.0, frac = 0.0, fracshft = 10.0;
    int c, dbl = 0, sign = 1, signexpo = 1;

    SKIPWS();
    c = GETC();
    if (c == '-') {
        sign = -1;
        c = GETC();
    }
    if (c == '0') {
        c = GETC();
        goto skip;
    }

    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        ival *= 10;
        ival += c - '0';
        c = GETC();
    }

skip:
    if (c != '.') goto skipfrac;

    dbl = 1;

    c = GETC();
    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        frac += (double)(c - '0') / fracshft;
        fracshft *= 10.0;
        c = GETC();
    }

skipfrac:
    if (c != 'e' && c != 'E') goto skipexpo;

    dbl = 1;

    c = GETC();
    if (c == '+')
        c = GETC();
    else if (c == '-') {
        signexpo = -1;
        c = GETC();
    }

    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        expo *= 10;
        expo += c - '0';
        c = GETC();
    }

skipexpo:
    UNGETC(c);

    if (dbl) {
        dval = sign * (long long) ival;
        dval += sign * frac;
        dval *= pow(10.0, (double) signexpo * expo);
    }

    zzjson = config->calloc(1, sizeof(ZZJSON));
    if (!zzjson) {
        MEMERROR();
        return NULL;
    }
    if (dbl) {
        zzjson->type = ZZJSON_NUMBER_DOUBLE;
        zzjson->value.number.val.dval = dval;
    } else {
        zzjson->type = sign < 0 ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
        zzjson->value.number.val.ival = ival;
    }
    
    return zzjson;
}
Example #29
0
int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
{
  HOOK *ptr;
  BUFFER command, pattern;
  int rc, not = 0;
  regex_t *rx = NULL;
  pattern_t *pat = NULL;
  char path[_POSIX_PATH_MAX];

  mutt_buffer_init (&pattern);
  mutt_buffer_init (&command);

  if (*s->dptr == '!')
  {
    s->dptr++;
    SKIPWS (s->dptr);
    not = 1;
  }

  mutt_extract_token (&pattern, s, 0);

  if (!MoreArgs (s))
  {
    strfcpy (err->data, _("too few arguments"), err->dsize);
    goto error;
  }

  mutt_extract_token (&command, s, (data & (M_FOLDERHOOK | M_SENDHOOK | M_SEND2HOOK | M_ACCOUNTHOOK | M_REPLYHOOK)) ?  M_TOKEN_SPACE : 0);

  if (!command.data)
  {
    strfcpy (err->data, _("too few arguments"), err->dsize);
    goto error;
  }

  if (MoreArgs (s))
  {
    strfcpy (err->data, _("too many arguments"), err->dsize);
    goto error;
  }

  if (data & (M_FOLDERHOOK | M_MBOXHOOK))
  {
    strfcpy (path, pattern.data, sizeof (path));
    _mutt_expand_path (path, sizeof (path), 1);
    FREE (&pattern.data);
    memset (&pattern, 0, sizeof (pattern));
    pattern.data = safe_strdup (path);
  }
  else if (DefaultHook && !(data & (M_CHARSETHOOK | M_ICONVHOOK | M_ACCOUNTHOOK))
           && (!WithCrypto || !(data & M_CRYPTHOOK))
      )
  {
    char tmp[HUGE_STRING];

    /* At this stage remain only message-hooks, reply-hooks, send-hooks,
     * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
     * patterns. If given a simple regexp, we expand $default_hook.
     */
    strfcpy (tmp, pattern.data, sizeof (tmp));
    mutt_check_simple (tmp, sizeof (tmp), DefaultHook);
    FREE (&pattern.data);
    memset (&pattern, 0, sizeof (pattern));
    pattern.data = safe_strdup (tmp);
  }

  if (data & (M_MBOXHOOK | M_SAVEHOOK | M_FCCHOOK))
  {
    strfcpy (path, command.data, sizeof (path));
    mutt_expand_path (path, sizeof (path));
    FREE (&command.data);
    memset (&command, 0, sizeof (command));
    command.data = safe_strdup (path);
  }

  /* check to make sure that a matching hook doesn't already exist */
  for (ptr = Hooks; ptr; ptr = ptr->next)
  {
    if (ptr->type == data &&
	ptr->rx.not == not &&
	!mutt_strcmp (pattern.data, ptr->rx.pattern))
    {
      if (data & (M_FOLDERHOOK | M_SENDHOOK | M_SEND2HOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK | M_REPLYHOOK))
      {
	/* these hooks allow multiple commands with the same
	 * pattern, so if we've already seen this pattern/command pair, just
	 * ignore it instead of creating a duplicate */
	if (!mutt_strcmp (ptr->command, command.data))
	{
	  FREE (&command.data);
	  FREE (&pattern.data);
	  return 0;
	}
      }
      else
      {
	/* other hooks only allow one command per pattern, so update the
	 * entry with the new command.  this currently does not change the
	 * order of execution of the hooks, which i think is desirable since
	 * a common action to perform is to change the default (.) entry
	 * based upon some other information. */
	FREE (&ptr->command);
	ptr->command = command.data;
	FREE (&pattern.data);
	return 0;
      }
    }
    if (!ptr->next)
      break;
  }

  if (data & (M_SENDHOOK | M_SEND2HOOK | M_SAVEHOOK | M_FCCHOOK | M_MESSAGEHOOK | M_REPLYHOOK))
  {
    if ((pat = mutt_pattern_comp (pattern.data,
	   (data & (M_SENDHOOK | M_SEND2HOOK | M_FCCHOOK)) ? 0 : M_FULL_MSG,
				  err)) == NULL)
      goto error;
  }
  else
  {
    /* Hooks not allowing full patterns: Check syntax of regexp */
    rx = safe_malloc (sizeof (regex_t));
#ifdef M_CRYPTHOOK
    if ((rc = REGCOMP (rx, NONULL(pattern.data), ((data & (M_CRYPTHOOK|M_CHARSETHOOK|M_ICONVHOOK)) ? REG_ICASE : 0))) != 0)
#else
    if ((rc = REGCOMP (rx, NONULL(pattern.data), (data & (M_CHARSETHOOK|M_ICONVHOOK)) ? REG_ICASE : 0)) != 0)
#endif /* M_CRYPTHOOK */
    {
      regerror (rc, rx, err->data, err->dsize);
      FREE (&rx);
      goto error;
    }
  }

  if (ptr)
  {
    ptr->next = safe_calloc (1, sizeof (HOOK));
    ptr = ptr->next;
  }
  else
    Hooks = ptr = safe_calloc (1, sizeof (HOOK));
  ptr->type = data;
  ptr->command = command.data;
  ptr->pattern = pat;
  ptr->rx.pattern = pattern.data;
  ptr->rx.rx = rx;
  ptr->rx.not = not;
  return 0;

error:
  FREE (&pattern.data);
  FREE (&command.data);
  return (-1);
}
Example #30
0
static char *parse_string(ZZJSON_CONFIG *config) {
    unsigned int len = 16, pos = 0;
    int c;
    char *str = NULL;

    SKIPWS();
    c = GETC();
    if (c != '"') {
        ERROR("string: expected \" at the start");
        return NULL;
    }

    str = config->malloc(len);
    if (!str) {
        MEMERROR();
        return NULL;
    }
    c = GETC();
    while (c > 0 && c != '"') {
        if (!ALLOW_CONTROL_CHARS && c >= 0 && c <= 31) {
            ERROR("string: control characters not allowed");
            goto errout;
        }
        if (c == '\\') {
            c = GETC();
            switch (c) {
                case 'b': c = '\b'; break;
                case 'f': c = '\f'; break;
                case 'n': c = '\n'; break;
                case 'r': c = '\r'; break;
                case 't': c = '\t'; break;
                case 'u': {
                    UNGETC(c);    /* ignore \uHHHH, copy verbatim */
                    c = '\\';
                    break;
                }
                case '\\': case '/': case '"':
                          break;
                default:
                    if (!ALLOW_ILLEGAL_ESCAPE) {
                        ERROR("string: illegal escape character");
                        goto errout;
                    }
            }
        }
        str[pos++] = c;
        if (pos == len-1) {
            void *tmp = str;
            len *= 2;
            str = config->realloc(str, len);
            if (!str) {
                MEMERROR();
                str = tmp;
                goto errout;
            }
        }
        c = GETC();
    }
    if (c != '"') {
        ERROR("string: expected \" at the end");
        goto errout;
    }
    str[pos] = 0;
    return str;

errout:
    config->free(str);
    return NULL;
}