From 6ab0a033e52ed0e31feadec942f3d2c4dc8040b1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Mon, 19 Jul 2010 20:56:54 +0000 Subject: [PATCH] * duplicate memreadline & bmstrcasestr to a const and non const version * follow changes in citserver where appropriate. --- .gitignore | 1 + citadel/internet_addressing.c | 10 +- citadel/modules/imap/imap_fetch.c | 2 +- citadel/modules/imap/imap_store.c | 2 +- citadel/modules/imap/serv_imap.c | 2 +- citadel/modules/openid/serv_openid_rp.c | 8 +- citadel/modules/pop3/serv_pop3.c | 2 +- citadel/modules/smtp/serv_smtp.c | 2 +- citadel/modules/wiki/serv_wiki.c | 2 +- libcitadel/lib/libcitadel.h | 12 +- libcitadel/lib/tools.c | 153 +++++++++++++++++++++++- 11 files changed, 172 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index ba73ec511..0966e021d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.changes *.deb *.tar.gz +webcit-* diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index c448001d1..7a9f4b078 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -864,13 +864,13 @@ char *rfc822_fetch_field(const char *rfc822, const char *fieldname) { snprintf(fieldhdr, sizeof fieldhdr, "%s:", fieldname); /* Locate the end of the headers, so we don't run past that point */ - end_of_headers = bmstrcasestr(rfc822, "\n\r\n"); + end_of_headers = cbmstrcasestr(rfc822, "\n\r\n"); if (end_of_headers == NULL) { - end_of_headers = bmstrcasestr(rfc822, "\n\n"); + end_of_headers = cbmstrcasestr(rfc822, "\n\n"); } if (end_of_headers == NULL) return (NULL); - field_start = bmstrcasestr(rfc822, fieldhdr); + field_start = cbmstrcasestr(rfc822, fieldhdr); if (field_start == NULL) return(NULL); if (field_start > end_of_headers) return(NULL); @@ -878,11 +878,11 @@ char *rfc822_fetch_field(const char *rfc822, const char *fieldname) { strcpy(fieldbuf, ""); ptr = field_start; - ptr = memreadline(ptr, fieldbuf, SIZ-strlen(fieldbuf) ); + ptr = cmemreadline(ptr, fieldbuf, SIZ-strlen(fieldbuf) ); while ( (isspace(ptr[0])) && (ptr < end_of_headers) ) { strcat(fieldbuf, " "); cont = &fieldbuf[strlen(fieldbuf)]; - ptr = memreadline(ptr, cont, SIZ-strlen(fieldbuf) ); + ptr = cmemreadline(ptr, cont, SIZ-strlen(fieldbuf) ); striplt(cont); } diff --git a/citadel/modules/imap/imap_fetch.c b/citadel/modules/imap/imap_fetch.c index 0ee327cb8..0a6ee4f1e 100644 --- a/citadel/modules/imap/imap_fetch.c +++ b/citadel/modules/imap/imap_fetch.c @@ -946,7 +946,7 @@ void imap_fetch_bodystructure (long msgnum, const char *item, ptr = rfc822; do { - ptr = memreadline(ptr, buf, sizeof buf); + ptr = cmemreadline(ptr, buf, sizeof buf); ++lines; if ((IsEmptyStr(buf)) && (rfc822_body == NULL)) { rfc822_body = ptr; diff --git a/citadel/modules/imap/imap_store.c b/citadel/modules/imap/imap_store.c index 845690df7..4b2f1b45d 100644 --- a/citadel/modules/imap/imap_store.c +++ b/citadel/modules/imap/imap_store.c @@ -105,7 +105,7 @@ void imap_do_store(citimap_command *Cmd) { if (Cmd->num_parms < 2) return; oper = Cmd->Params[0].Key; - if (bmstrcasestr(oper, ".SILENT")) { + if (cbmstrcasestr(oper, ".SILENT")) { silent = 1; } diff --git a/citadel/modules/imap/serv_imap.c b/citadel/modules/imap/serv_imap.c index 5ddae608a..baee87c1a 100644 --- a/citadel/modules/imap/serv_imap.c +++ b/citadel/modules/imap/serv_imap.c @@ -1426,7 +1426,7 @@ void imap_command_loop(void) CtdlLogPrintf(CTDL_INFO, "IMAP: \n"); } else if ((Imap->authstate == imap_as_expecting_multilineusername) || - bmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) { + cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) { CtdlLogPrintf(CTDL_INFO, "IMAP: LOGIN...\n"); } else { diff --git a/citadel/modules/openid/serv_openid_rp.c b/citadel/modules/openid/serv_openid_rp.c index 384e2b6e0..638a77bdd 100644 --- a/citadel/modules/openid/serv_openid_rp.c +++ b/citadel/modules/openid/serv_openid_rp.c @@ -503,7 +503,7 @@ void extract_link(StrBuf *target_buf, const char *rel, long repllen, StrBuf *sou ptr = ChrPtr(source_buf); FlushStrBuf(target_buf); - while (ptr = bmstrcasestr(ptr, "'); @@ -512,7 +512,7 @@ void extract_link(StrBuf *target_buf, const char *rel, long repllen, StrBuf *sou for (i=0; i < 1; i++ ){ len = link_tag_end - link_tag_start; - rel_start = bmstrcasestr(link_tag_start, "rel="); + rel_start = cbmstrcasestr(link_tag_start, "rel="); if ((rel_start == NULL) || (rel_start > link_tag_end)) continue; @@ -530,7 +530,7 @@ void extract_link(StrBuf *target_buf, const char *rel, long repllen, StrBuf *sou if (strncasecmp(rel, rel_start, repllen)!= 0) continue; /* didn't match? never mind... */ - href_start = bmstrcasestr(link_tag_start, "href="); + href_start = cbmstrcasestr(link_tag_start, "href="); if ((href_start == NULL) || (href_start >= link_tag_end)) continue; @@ -842,7 +842,7 @@ void cmd_oidf(char *argbuf) { curl_easy_cleanup(curl); curl_formfree(formpost); - if (bmstrcasestr(ChrPtr(ReplyBuf), "is_valid:true")) { + if (cbmstrcasestr(ChrPtr(ReplyBuf), "is_valid:true")) { oiddata->verified = 1; } FreeStrBuf(&ReplyBuf); diff --git a/citadel/modules/pop3/serv_pop3.c b/citadel/modules/pop3/serv_pop3.c index 33fa1203d..2c1402dbd 100644 --- a/citadel/modules/pop3/serv_pop3.c +++ b/citadel/modules/pop3/serv_pop3.c @@ -420,7 +420,7 @@ void pop3_top(char *argbuf) { cprintf("+OK Message %d:\r\n", which_one); ptr = ChrPtr(msgtext); - while (ptr = memreadline(ptr, buf, (sizeof buf - 2)), + while (ptr = cmemreadline(ptr, buf, (sizeof buf - 2)), ( (*ptr != 0) && (done == 0))) { strcat(buf, "\r\n"); if (in_body == 1) { diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index 7d1e26f49..1d7dd0e7e 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -1002,7 +1002,7 @@ void smtp_try(const char *key, const char *addr, int *status, scan_done = 0; ptr = msgtext; do { - if (ptr = memreadline(ptr, buf, sizeof buf), *ptr == 0) { + if (ptr = cmemreadline(ptr, buf, sizeof buf), *ptr == 0) { scan_done = 1; } if (!strncasecmp(buf, "From:", 5)) { diff --git a/citadel/modules/wiki/serv_wiki.c b/citadel/modules/wiki/serv_wiki.c index 1011546cf..624138b1c 100644 --- a/citadel/modules/wiki/serv_wiki.c +++ b/citadel/modules/wiki/serv_wiki.c @@ -95,7 +95,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { int nbytes = 0; char *diffbuf = NULL; size_t diffbuf_len = 0; - const char *ptr = NULL; + char *ptr = NULL; if (!CCC->logged_in) return(0); /* Only do this if logged in. */ diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 92ab07f3e..44e1544e7 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -319,8 +319,10 @@ int haschar(const char *st, int ch); void remove_token(char *source, int parmnum, char separator); void fmt_date(char *buf, size_t n, time_t thetime, int seconds); int is_msg_in_sequence_set(const char *mset, long msgnum); -const char *memreadline(const char *start, char *buf, int maxlen); -const char *memreadlinelen(const char *start, char *buf, int maxlen, int *retlen); +char *memreadline(char *start, char *buf, int maxlen); +char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen); +const char *cmemreadline(const char *start, char *buf, int maxlen); +const char *cmemreadlinelen(const char *start, char *buf, int maxlen, int *retlen); #define IsEmptyStr(a) ((a)[0] == '\0') #define num_parms(source) num_tokens(source,(char)'|') int stripout(char *str, char leftboundary, char rightboundary); @@ -330,8 +332,10 @@ void urlesc(char *outbuf, size_t oblen, char *strbuf); char *CtdlTempFileName(char *prefix1, int prefix2); FILE *CtdlTempFile(void); void generate_uuid(char *buf); -const char *bmstrcasestr(const char *text, const char *pattern); -const char *bmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen); +char *bmstrcasestr(char *text, const char *pattern); +char *bmstrcasestr_len(char *text, size_t textlen, const char *pattern, size_t patlen); +const char *cbmstrcasestr(const char *text, const char *pattern); +const char *cbmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen); void CtdlMakeTempFileName(char *name, int len); char *rfc2047encode(char *line, long length); int is_msg_in_mset(const char *mset, long msgnum); diff --git a/libcitadel/lib/tools.c b/libcitadel/lib/tools.c index da37f7f08..73f8e778f 100644 --- a/libcitadel/lib/tools.c +++ b/libcitadel/lib/tools.c @@ -629,7 +629,65 @@ int is_msg_in_sequence_set(const char *mset, long msgnum) { * \param maxlen Size of string buffer * \return Pointer to the source memory right after we stopped reading. */ -const char *memreadline(const char *start, char *buf, int maxlen) +char *memreadline(char *start, char *buf, int maxlen) +{ + char ch; + char *ptr; + int len = 0; /**< tally our own length to avoid strlen() delays */ + + ptr = start; + + while (1) { + ch = *ptr++; + if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) { + buf[len++] = ch; + } + if ((ch == 10) || (ch == 0)) { + buf[len] = 0; + return ptr; + } + } +} + + +/** + * \brief Utility function to "readline" from memory + * \param start Location in memory from which we are reading. + * \param buf the buffer to place the string in. + * \param maxlen Size of string buffer + * \param retlen the length of the returned string + * \return Pointer to the source memory right after we stopped reading. + */ +char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen) +{ + char ch; + char *ptr; + int len = 0; /**< tally our own length to avoid strlen() delays */ + + ptr = start; + + while (1) { + ch = *ptr++; + if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) { + buf[len++] = ch; + } + if ((ch == 10) || (ch == 0)) { + buf[len] = 0; + *retlen = len; + return ptr; + } + } +} + + +/** + * \brief Utility function to "readline" from memory + * \param start Location in memory from which we are reading. + * \param buf the buffer to place the string in. + * \param maxlen Size of string buffer + * \return Pointer to the source memory right after we stopped reading. + */ +const char *cmemreadline(const char *start, char *buf, int maxlen) { char ch; const char *ptr; @@ -658,7 +716,7 @@ const char *memreadline(const char *start, char *buf, int maxlen) * \param retlen the length of the returned string * \return Pointer to the source memory right after we stopped reading. */ -const char *memreadlinelen(const char *start, char *buf, int maxlen, int *retlen) +const char *cmemreadlinelen(const char *start, char *buf, int maxlen, int *retlen) { char ch; const char *ptr; @@ -805,7 +863,7 @@ void generate_uuid(char *buf) { * The code is roughly based on the strstr() replacement from 'tin' written * by Urs Jannsen. */ -inline static const char *_bmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen) { +inline static char *_bmstrcasestr_len(char *text, size_t textlen, const char *pattern, size_t patlen) { register unsigned char *p, *t; register int i, j, *delta; @@ -863,7 +921,7 @@ inline static const char *_bmstrcasestr_len(const char *text, size_t textlen, co * The code is roughly based on the strstr() replacement from 'tin' written * by Urs Jannsen. */ -const char *bmstrcasestr(const char *text, const char *pattern) { +char *bmstrcasestr(char *text, const char *pattern) { size_t textlen; size_t patlen; @@ -876,10 +934,95 @@ const char *bmstrcasestr(const char *text, const char *pattern) { return _bmstrcasestr_len(text, textlen, pattern, patlen); } -const char *bmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen) { +char *bmstrcasestr_len(char *text, size_t textlen, const char *pattern, size_t patlen) { return _bmstrcasestr_len(text, textlen, pattern, patlen); } + + + +/* + * bmstrcasestr() -- case-insensitive substring search + * + * This uses the Boyer-Moore search algorithm and is therefore quite fast. + * The code is roughly based on the strstr() replacement from 'tin' written + * by Urs Jannsen. + */ +inline static const char *_cbmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen) { + + register unsigned char *p, *t; + register int i, j, *delta; + register size_t p1; + int deltaspace[256]; + + if (!text) return(NULL); + if (!pattern) return(NULL); + + /* algorithm fails if pattern is empty */ + if ((p1 = patlen) == 0) + return (text); + + /* code below fails (whenever i is unsigned) if pattern too long */ + if (p1 > textlen) + return (NULL); + + /* set up deltas */ + delta = deltaspace; + for (i = 0; i <= 255; i++) + delta[i] = p1; + for (p = (unsigned char *) pattern, i = p1; --i > 0;) + delta[tolower(*p++)] = i; + + /* + * From now on, we want patlen - 1. + * In the loop below, p points to the end of the pattern, + * t points to the end of the text to be tested against the + * pattern, and i counts the amount of text remaining, not + * including the part to be tested. + */ + p1--; + p = (unsigned char *) pattern + p1; + t = (unsigned char *) text + p1; + i = textlen - patlen; + while(1) { + if (tolower(p[0]) == tolower(t[0])) { + if (strncasecmp ((const char *)(p - p1), (const char *)(t - p1), p1) == 0) { + return ((char *)t - p1); + } + } + j = delta[tolower(t[0])]; + if (i < j) + break; + i -= j; + t += j; + } + return (NULL); +} + +/* + * bmstrcasestr() -- case-insensitive substring search + * + * This uses the Boyer-Moore search algorithm and is therefore quite fast. + * The code is roughly based on the strstr() replacement from 'tin' written + * by Urs Jannsen. + */ +const char *cbmstrcasestr(const char *text, const char *pattern) { + size_t textlen; + size_t patlen; + + if (!text) return(NULL); + if (!pattern) return(NULL); + + textlen = strlen (text); + patlen = strlen (pattern); + + return _cbmstrcasestr_len(text, textlen, pattern, patlen); +} + +const char *cbmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen) { + return _cbmstrcasestr_len(text, textlen, pattern, patlen); +} + /* * Local replacement for controversial C library function that generates * names for temporary files. Included to shut up compiler warnings. -- 2.30.2