static int fs_sis_queue_init(struct fs *_fs, const char *args, const struct fs_settings *set) { struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs; const char *p, *parent_name, *parent_args, *error; /* <queue_dir>:<parent fs>[:<args>] */ p = strchr(args, ':'); if (p == NULL || p[1] == '\0') { fs_set_error(_fs, "Parent filesystem not given as parameter"); return -1; } fs->queue_dir = i_strdup_until(args, p); parent_name = p + 1; parent_args = strchr(parent_name, ':'); if (parent_args == NULL) parent_args = ""; else parent_name = t_strdup_until(parent_name, parent_args++); if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) { fs_set_error(_fs, "%s: %s", parent_name, error); return -1; } return 0; }
int mbox_from_parse(const unsigned char *msg, size_t size, time_t *time_r, int *tz_offset_r, char **sender_r) { const unsigned char *msg_start, *sender_end, *msg_end; struct tm tm; int esc, alt_stamp, timezone_secs = 0, seen_timezone = FALSE; time_t t; *time_r = (time_t)-1; *sender_r = NULL; /* <sender> <date> <moreinfo> */ msg_start = msg; msg_end = msg + size; /* get sender */ if (msg < msg_end && *msg == '"') { /* "x y z"@domain - skip the quoted part */ esc = FALSE; msg++; while (msg < msg_end && (*msg != '"' || esc)) { if (*msg == '\r' || *msg == '\n') return -1; esc = *msg == '\\'; msg++; } msg++; } while (msg < msg_end && *msg != ' ') { if (*msg == '\r' || *msg == '\n') return -1; msg++; } sender_end = msg; while (msg < msg_end && *msg == ' ') msg++; /* next 29 chars should be in the date in asctime() format, eg. "Thu Nov 9 22:33:52 2001 +0300" - Some put the timezone before the year - Some use a named timezone before or after year, which we ignore - Some don't include seconds (-3) - Some don't include timezone (-5) */ if (msg+29-3-5 > msg_end) return -1; memset(&tm, 0, sizeof(tm)); /* skip weekday */ msg += 4; /* month */ if (mbox_parse_month(msg, &tm) < 0) { /* Try alternate timestamp: "Thu, 9 Nov 2002 22:33:52" */ alt_stamp = TRUE; msg++; if (!i_isdigit(msg[0])) return -1; tm.tm_mday = msg[0]-'0'; msg++; if (i_isdigit(msg[0])) { tm.tm_mday = tm.tm_mday*10 + msg[0]-'0'; msg++; } if (msg[0] != ' ') return -1; msg++; if (mbox_parse_month(msg, &tm) < 0) return -1; msg += 4; if (mbox_parse_year(msg, &tm) < 0) return -1; msg += 5; } else { alt_stamp = FALSE; msg += 4; /* day. single digit is usually preceded by extra space */ if (msg[0] == ' ') msg++; if (msg[1] == ' ') { if (!i_isdigit(msg[0])) return -1; tm.tm_mday = msg[0]-'0'; msg += 2; } else { if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ') return -1; tm.tm_mday = (msg[0]-'0') * 10 + (msg[1]-'0'); msg += 3; } } if (tm.tm_mday == 0) tm.tm_mday = 1; /* hour */ if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':') return -1; tm.tm_hour = (msg[0]-'0') * 10 + (msg[1]-'0'); msg += 3; /* minute */ if (!i_isdigit(msg[0]) || !i_isdigit(msg[1])) return -1; tm.tm_min = (msg[0]-'0') * 10 + (msg[1]-'0'); msg += 2; /* optional second */ if (msg[0] == ':') { msg++; if (!i_isdigit(msg[0]) || !i_isdigit(msg[1])) return -1; tm.tm_sec = (msg[0]-'0') * 10 + (msg[1]-'0'); msg += 2; if (!alt_stamp) { if (msg[0] == ' ') msg++; else return -1; } } else if (!alt_stamp) { if (msg[0] != ' ') return -1; msg++; } /* optional named timezone */ if (alt_stamp) ; else if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || !i_isdigit(msg[2]) || !i_isdigit(msg[3])) { /* skip to next space */ while (msg < msg_end && *msg != ' ') { if (*msg == '\r' || *msg == '\n') return -1; msg++; } if (msg+5 > msg_end) return -1; msg++; } else if ((msg[0] == '-' || msg[0] == '+') && i_isdigit(msg[1]) && i_isdigit(msg[2]) && i_isdigit(msg[3]) && i_isdigit(msg[4]) && msg[5] == ' ') { /* numeric timezone, use it */ seen_timezone = TRUE; timezone_secs = (msg[1]-'0') * 10*60*60 + (msg[2]-'0') * 60*60 + (msg[3]-'0') * 10 + (msg[4]-'0'); if (msg[0] == '-') timezone_secs = -timezone_secs; msg += 6; } if (!alt_stamp) { /* year */ if (mbox_parse_year(msg, &tm) < 0) return -1; msg += 4; } tm.tm_isdst = -1; if (!seen_timezone && msg != msg_end && msg[0] == ' ' && (msg[1] == '-' || msg[1] == '+') && i_isdigit(msg[2]) && i_isdigit(msg[3]) && i_isdigit(msg[4]) && i_isdigit(msg[5])) { seen_timezone = TRUE; timezone_secs = (msg[2]-'0') * 10*60*60 + (msg[3]-'0') * 60*60 + (msg[4]-'0') * 10 + (msg[5]-'0'); if (msg[1] == '-') timezone_secs = -timezone_secs; } if (seen_timezone) { t = utc_mktime(&tm); if (t == (time_t)-1) return -1; t -= timezone_secs; *time_r = t; *tz_offset_r = timezone_secs/60; } else { /* assume local timezone */ *time_r = mktime(&tm); *tz_offset_r = utc_offset(localtime(time_r), *time_r); } *sender_r = i_strdup_until(msg_start, sender_end); return 0; }