/** * @param s: a string * @return: an integer */ int lengthOfLongestSubstring(string s) { // write your code here int ans = 0; if(!s.size()) return ans; vector<bool> haschar(256); int l = 0, n = s.size(), len = 0; for(int r = 0; r < n; ++ r){ int idx = (int)s[r]; if(!haschar[idx]){ ++ len; haschar[idx] = 1; ans = max(ans, len); }else{ int targ_idx = idx; idx = (int)s[l]; haschar[targ_idx] = 1; while(targ_idx != idx && l < r){ haschar[idx] = false; -- len; ++ l; idx = (int)s[l]; } ++ l; } } return ans; }
/* * Aliasing for network mail. * (Error messages have been commented out, because this is a server.) */ int alias(char *name) { /* process alias and routing info for mail */ struct CitContext *CCC = CC; FILE *fp; int a, i; char aaa[SIZ], bbb[SIZ]; char *ignetcfg = NULL; char *ignetmap = NULL; int at = 0; char node[64]; char testnode[64]; char buf[SIZ]; char original_name[256]; safestrncpy(original_name, name, sizeof original_name); striplt(name); remove_any_whitespace_to_the_left_or_right_of_at_symbol(name); stripallbut(name, '<', '>'); fp = fopen(file_mail_aliases, "r"); if (fp == NULL) { fp = fopen("/dev/null", "r"); } if (fp == NULL) { return (MES_ERROR); } strcpy(aaa, ""); strcpy(bbb, ""); while (fgets(aaa, sizeof aaa, fp) != NULL) { while (isspace(name[0])) strcpy(name, &name[1]); aaa[strlen(aaa) - 1] = 0; strcpy(bbb, ""); for (a = 0; aaa[a] != '\0'; ++a) { if (aaa[a] == ',') { strcpy(bbb, &aaa[a + 1]); aaa[a] = 0; break; } } if (!strcasecmp(name, aaa)) strcpy(name, bbb); } fclose(fp); /* Hit the Global Address Book */ if (CtdlDirectoryLookup(aaa, name, sizeof aaa) == 0) { strcpy(name, aaa); } if (strcasecmp(original_name, name)) { MSG_syslog(LOG_INFO, "%s is being forwarded to %s\n", original_name, name); } /* Change "user @ xxx" to "user" if xxx is an alias for this host */ for (a=0; name[a] != '\0'; ++a) { if (name[a] == '@') { if (CtdlHostAlias(&name[a+1]) == hostalias_localhost) { name[a] = 0; MSG_syslog(LOG_INFO, "Changed to <%s>\n", name); break; } } } /* determine local or remote type, see citadel.h */ at = haschar(name, '@'); if (at == 0) return(MES_LOCAL); /* no @'s - local address */ if (at > 1) return(MES_ERROR); /* >1 @'s - invalid address */ remove_any_whitespace_to_the_left_or_right_of_at_symbol(name); /* figure out the delivery mode */ extract_token(node, name, 1, '@', sizeof node); /* If there are one or more dots in the nodename, we assume that it * is an FQDN and will attempt SMTP delivery to the Internet. */ if (haschar(node, '.') > 0) { return(MES_INTERNET); } /* Otherwise we look in the IGnet maps for a valid Citadel node. * Try directly-connected nodes first... */ ignetcfg = CtdlGetSysConfig(IGNETCFG); for (i=0; i<num_tokens(ignetcfg, '\n'); ++i) { extract_token(buf, ignetcfg, i, '\n', sizeof buf); extract_token(testnode, buf, 0, '|', sizeof testnode); if (!strcasecmp(node, testnode)) { free(ignetcfg); return(MES_IGNET); } } free(ignetcfg); /* * Then try nodes that are two or more hops away. */ ignetmap = CtdlGetSysConfig(IGNETMAP); for (i=0; i<num_tokens(ignetmap, '\n'); ++i) { extract_token(buf, ignetmap, i, '\n', sizeof buf); extract_token(testnode, buf, 0, '|', sizeof testnode); if (!strcasecmp(node, testnode)) { free(ignetmap); return(MES_IGNET); } } free(ignetmap); /* If we get to this point it's an invalid node name */ return (MES_ERROR); }
/* * convert_field() is a helper function for convert_internet_message(). * Given start/end positions for an rfc822 field, it converts it to a Citadel * field if it wants to, and unfolds it if necessary. * * Returns 1 if the field was converted and inserted into the Citadel message * structure, implying that the source field should be removed from the * message text. */ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { char *key, *value, *valueend; long len; const char *pos; int i; const char *colonpos = NULL; int processed = 0; char user[1024]; char node[1024]; char name[1024]; char addr[1024]; time_t parsed_date; long valuelen; for (pos = end; pos >= beg; pos--) { if (*pos == ':') colonpos = pos; } if (colonpos == NULL) return(0); /* no colon? not a valid header line */ len = end - beg; key = malloc(len + 2); memcpy(key, beg, len + 1); key[len] = '\0'; valueend = key + len; * ( key + (colonpos - beg) ) = '\0'; value = &key[(colonpos - beg) + 1]; /* printf("Header: [%s]\nValue: [%s]\n", key, value); */ unfold_rfc822_field(&value, &valueend); valuelen = valueend - value + 1; /* printf("UnfoldedValue: [%s]\n", value); */ /* * Here's the big rfc822-to-citadel loop. */ /* Date/time is converted into a unix timestamp. If the conversion * fails, we replace it with the time the message arrived locally. */ if (!strcasecmp(key, "Date")) { parsed_date = parsedate(value); if (parsed_date < 0L) parsed_date = time(NULL); if (CM_IsEmpty(msg, eTimestamp)) CM_SetFieldLONG(msg, eTimestamp, parsed_date); processed = 1; } else if (!strcasecmp(key, "From")) { process_rfc822_addr(value, user, node, name); syslog(LOG_DEBUG, "Converted to <%s@%s> (%s)\n", user, node, name); snprintf(addr, sizeof(addr), "%s@%s", user, node); if (CM_IsEmpty(msg, eAuthor) && !IsEmptyStr(name)) CM_SetField(msg, eAuthor, name, strlen(name)); if (CM_IsEmpty(msg, erFc822Addr) && !IsEmptyStr(addr)) CM_SetField(msg, erFc822Addr, addr, strlen(addr)); processed = 1; } else if (!strcasecmp(key, "Subject")) { if (CM_IsEmpty(msg, eMsgSubject)) CM_SetField(msg, eMsgSubject, value, valuelen); processed = 1; } else if (!strcasecmp(key, "List-ID")) { if (CM_IsEmpty(msg, eListID)) CM_SetField(msg, eListID, value, valuelen); processed = 1; } else if (!strcasecmp(key, "To")) { if (CM_IsEmpty(msg, eRecipient)) CM_SetField(msg, eRecipient, value, valuelen); processed = 1; } else if (!strcasecmp(key, "CC")) { if (CM_IsEmpty(msg, eCarbonCopY)) CM_SetField(msg, eCarbonCopY, value, valuelen); processed = 1; } else if (!strcasecmp(key, "Message-ID")) { if (!CM_IsEmpty(msg, emessageId)) { syslog(LOG_WARNING, "duplicate message id\n"); } else { char *pValue; long pValueLen; pValue = value; pValueLen = valuelen; /* Strip angle brackets */ while (haschar(pValue, '<') > 0) { pValue ++; pValueLen --; } for (i = 0; i <= pValueLen; ++i) if (pValue[i] == '>') { pValueLen = i; break; } CM_SetField(msg, emessageId, pValue, pValueLen); } processed = 1; } else if (!strcasecmp(key, "Return-Path")) { if (CM_IsEmpty(msg, eMessagePath)) CM_SetField(msg, eMessagePath, value, valuelen); processed = 1; } else if (!strcasecmp(key, "Envelope-To")) { if (CM_IsEmpty(msg, eenVelopeTo)) CM_SetField(msg, eenVelopeTo, value, valuelen); processed = 1; } else if (!strcasecmp(key, "References")) { CM_SetField(msg, eWeferences, value, valuelen); processed = 1; } else if (!strcasecmp(key, "Reply-To")) { CM_SetField(msg, eReplyTo, value, valuelen); processed = 1; } else if (!strcasecmp(key, "In-reply-to")) { if (CM_IsEmpty(msg, eWeferences)) /* References: supersedes In-reply-to: */ CM_SetField(msg, eWeferences, value, valuelen); processed = 1; } /* Clean up and move on. */ free(key); /* Don't free 'value', it's actually the same buffer */ return processed; }
/* * Split an RFC822-style address into userid, host, and full name * */ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) { int a; strcpy(user, ""); strcpy(node, CtdlGetConfigStr("c_fqdn")); strcpy(name, ""); if (rfc822 == NULL) return; /* extract full name - first, it's From minus <userid> */ strcpy(name, rfc822); stripout(name, '<', '>'); /* strip anything to the left of a bang */ while ((!IsEmptyStr(name)) && (haschar(name, '!') > 0)) strcpy(name, &name[1]); /* and anything to the right of a @ or % */ for (a = 0; name[a] != '\0'; ++a) { if (name[a] == '@') { name[a] = 0; break; } if (name[a] == '%') { name[a] = 0; break; } } /* but if there are parentheses, that changes the rules... */ if ((haschar(rfc822, '(') == 1) && (haschar(rfc822, ')') == 1)) { strcpy(name, rfc822); stripallbut(name, '(', ')'); } /* but if there are a set of quotes, that supersedes everything */ if (haschar(rfc822, 34) == 2) { strcpy(name, rfc822); while ((!IsEmptyStr(name)) && (name[0] != 34)) { strcpy(&name[0], &name[1]); } strcpy(&name[0], &name[1]); for (a = 0; name[a] != '\0'; ++a) if (name[a] == 34) { name[a] = 0; break; } } /* extract user id */ strcpy(user, rfc822); /* first get rid of anything in parens */ stripout(user, '(', ')'); /* if there's a set of angle brackets, strip it down to that */ if ((haschar(user, '<') == 1) && (haschar(user, '>') == 1)) { stripallbut(user, '<', '>'); } /* strip anything to the left of a bang */ while ((!IsEmptyStr(user)) && (haschar(user, '!') > 0)) strcpy(user, &user[1]); /* and anything to the right of a @ or % */ for (a = 0; user[a] != '\0'; ++a) { if (user[a] == '@') { user[a] = 0; break; } if (user[a] == '%') { user[a] = 0; break; } } /* extract node name */ strcpy(node, rfc822); /* first get rid of anything in parens */ stripout(node, '(', ')'); /* if there's a set of angle brackets, strip it down to that */ if ((haschar(node, '<') == 1) && (haschar(node, '>') == 1)) { stripallbut(node, '<', '>'); } /* If no node specified, tack ours on instead */ if ( (haschar(node, '@')==0) && (haschar(node, '%')==0) && (haschar(node, '!')==0) ) { strcpy(node, CtdlGetConfigStr("c_nodename")); } else { /* strip anything to the left of a @ */ while ((!IsEmptyStr(node)) && (haschar(node, '@') > 0)) strcpy(node, &node[1]); /* strip anything to the left of a % */ while ((!IsEmptyStr(node)) && (haschar(node, '%') > 0)) strcpy(node, &node[1]); /* reduce multiple system bang paths to node!user */ while ((!IsEmptyStr(node)) && (haschar(node, '!') > 1)) strcpy(node, &node[1]); /* now get rid of the user portion of a node!user string */ for (a = 0; node[a] != '\0'; ++a) if (node[a] == '!') { node[a] = 0; break; } } /* strip leading and trailing spaces in all strings */ striplt(user); striplt(node); striplt(name); /* If we processed a string that had the address in angle brackets * but no name outside the brackets, we now have an empty name. In * this case, use the user portion of the address as the name. */ if ((IsEmptyStr(name)) && (!IsEmptyStr(user))) { strcpy(name, user); } }