/* * Go to the URL saved by push_destination() */ void pop_destination(void) { wcsession *WCC = WC; /* * If we are in the middle of a new user signup, the server may request that * we first pass through a registration screen. */ if ((WCC) && (WCC->need_regi)) { if ((WCC->PushedDestination != NULL) && (StrLength(WCC->PushedDestination) > 0)) { /* Registering will take us to the My Citadel Config room, so save our place */ StrBufAppendBufPlain(WCC->PushedDestination, HKEY("?go="), 0); StrBufUrlescAppend(WCC->PushedDestination, WCC->CurRoom.name, NULL); } WCC->need_regi = 0; display_reg(1); return; } /* * Do something reasonable if we somehow ended up requesting a pop without * having first done a push. */ if ( (!WCC) || (WCC->PushedDestination == NULL) || (StrLength(WCC->PushedDestination) == 0) ) { do_welcome(); return; } /* * All righty then! We have a destination saved, so go there now. */ if (verbose) syslog(LOG_DEBUG, "Pop: %s", ChrPtr(WCC->PushedDestination)); http_redirect(ChrPtr(WCC->PushedDestination)); }
/* * Offer the RSS feed button for this room */ void tmplput_rssbutton(StrBuf *Target, WCTemplputParams *TP) { StrBuf *FeedLink = NULL; FeedLink = NewStrBufPlain(HKEY("/feed_rss?go=")); StrBufUrlescAppend(FeedLink, WC->CurRoom.name, NULL); StrBufAppendPrintf(Target, "<a type=\"application/rss+xml\" href=\""); StrBufAppendBuf(Target, FeedLink, 0); StrBufAppendPrintf(Target, "\"><img src=\"static/webcit_icons/essen/16x16/rss.png\" alt=\"RSS\">"); StrBufAppendPrintf(Target, "</a>"); FreeStrBuf(&FeedLink); }
static void TestUrlescEncodeStdin(void) { int fdin = 0;// STDIN const char *Err; StrBuf *Target; StrBuf *Source; Source = NewStrBuf(); while (fdin == 0) { StrBufTCP_read_line(Source, &fdin, 0, &Err); Target = NewStrBuf(); StrBufUrlescAppend(Target, Source, NULL); TestRevalidateStrBuf(Target); printf("%s\n", ChrPtr(Target)); FreeStrBuf(&Target); } FreeStrBuf(&Source); }
/* * Setup an OpenID authentication */ void cmd_oids(char *argbuf) { struct CitContext *CCC = CC; /* CachedCitContext - performance boost */ const char *Pos = NULL; StrBuf *ArgBuf = NULL; StrBuf *ReplyBuf = NULL; StrBuf *return_to = NULL; StrBuf *RedirectUrl = NULL; ctdl_openid *oiddata; int discovery_succeeded = 0; if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); return; } Free_ctdl_openid ((ctdl_openid**)&CCC->openid_data); CCC->openid_data = oiddata = malloc(sizeof(ctdl_openid)); if (oiddata == NULL) { syslog(LOG_ALERT, "malloc() failed: %s", strerror(errno)); cprintf("%d malloc failed\n", ERROR + INTERNAL_ERROR); return; } memset(oiddata, 0, sizeof(ctdl_openid)); ArgBuf = NewStrBufPlain(argbuf, -1); oiddata->verified = 0; oiddata->claimed_id = NewStrBufPlain(NULL, StrLength(ArgBuf)); return_to = NewStrBufPlain(NULL, StrLength(ArgBuf)); StrBufExtract_NextToken(oiddata->claimed_id, ArgBuf, &Pos, '|'); StrBufExtract_NextToken(return_to, ArgBuf, &Pos, '|'); syslog(LOG_DEBUG, "User-Supplied Identifier is: %s", ChrPtr(oiddata->claimed_id)); /********** OpenID 2.0 section 7.3 - Discovery **********/ /* Section 7.3.1 says we have to attempt XRI based discovery. * No one is using this, no one is asking for it, no one wants it. * So we're not even going to bother attempting this mode. */ /* Attempt section 7.3.2 (Yadis discovery) and section 7.3.3 (HTML discovery); */ discovery_succeeded = perform_openid2_discovery(oiddata->claimed_id); if (discovery_succeeded == 0) { cprintf("%d There is no OpenID identity provider at this location.\n", ERROR); } else { /* * If we get to this point we are in possession of a valid OpenID Provider URL. */ syslog(LOG_DEBUG, "OP URI '%s' discovered using method %d", ChrPtr(oiddata->op_url), discovery_succeeded ); /* We have to "normalize" our Claimed ID otherwise it will cause some OP's to barf */ if (cbmstrcasestr(ChrPtr(oiddata->claimed_id), "://") == NULL) { StrBuf *cid = oiddata->claimed_id; oiddata->claimed_id = NewStrBufPlain(HKEY("http://")); StrBufAppendBuf(oiddata->claimed_id, cid, 0); FreeStrBuf(&cid); } /* * OpenID 2.0 section 9: request authentication * Assemble a URL to which the user-agent will be redirected. */ RedirectUrl = NewStrBufDup(oiddata->op_url); StrBufAppendBufPlain(RedirectUrl, HKEY("?openid.ns="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://specs.openid.net/auth/2.0"); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.mode=checkid_setup"), 0); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.claimed_id="), 0); StrBufUrlescAppend(RedirectUrl, oiddata->claimed_id, NULL); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.identity="), 0); StrBufUrlescAppend(RedirectUrl, oiddata->claimed_id, NULL); /* return_to tells the provider how to complete the round trip back to our site */ StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.return_to="), 0); StrBufUrlescAppend(RedirectUrl, return_to, NULL); /* Attribute Exchange * See: * http://openid.net/specs/openid-attribute-exchange-1_0.html * http://code.google.com/apis/accounts/docs/OpenID.html#endpoint * http://test-id.net/OP/AXFetch.aspx */ StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ns.ax="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://openid.net/srv/ax/1.0"); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.mode=fetch_request"), 0); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.required=firstname,lastname,friendly,nickname"), 0); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.firstname="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/first"); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.lastname="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/last"); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.friendly="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/friendly"); StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.nickname="), 0); StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/nickname"); syslog(LOG_DEBUG, "OpenID: redirecting client to %s", ChrPtr(RedirectUrl)); cprintf("%d %s\n", CIT_OK, ChrPtr(RedirectUrl)); } FreeStrBuf(&ArgBuf); FreeStrBuf(&ReplyBuf); FreeStrBuf(&return_to); FreeStrBuf(&RedirectUrl); }
/* * Scan a room's netconfig to determine whether it requires POP3 aggregation */ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data, OneRoomNetCfg *OneRNCFG) { const RoomNetCfgLine *pLine; void *vptr; pthread_mutex_lock(&POP3QueueMutex); if (GetHash(POP3QueueRooms, LKEY(qrbuf->QRnumber), &vptr)) { pthread_mutex_unlock(&POP3QueueMutex); EVP3CQ_syslog(LOG_DEBUG, "pop3client: [%ld] %s already in progress.", qrbuf->QRnumber, qrbuf->QRname); return; } pthread_mutex_unlock(&POP3QueueMutex); if (server_shutting_down) return; pLine = OneRNCFG->NetConfigs[pop3client]; while (pLine != NULL) { pop3aggr *cptr; cptr = (pop3aggr *) malloc(sizeof(pop3aggr)); memset(cptr, 0, sizeof(pop3aggr)); ///TODO do we need this? cptr->roomlist_parts=1; cptr->RoomName = NewStrBufPlain(qrbuf->QRname, -1); cptr->pop3user = NewStrBufDup(pLine->Value[1]); cptr->pop3pass = NewStrBufDup(pLine->Value[2]); cptr->Url = NewStrBuf(); cptr->Host = NewStrBufDup(pLine->Value[0]); cptr->keep = atol(ChrPtr(pLine->Value[3])); cptr->interval = atol(ChrPtr(pLine->Value[4])); StrBufAppendBufPlain(cptr->Url, HKEY("pop3://"), 0); StrBufUrlescUPAppend(cptr->Url, cptr->pop3user, NULL); StrBufAppendBufPlain(cptr->Url, HKEY(":"), 0); StrBufUrlescUPAppend(cptr->Url, cptr->pop3pass, NULL); StrBufAppendBufPlain(cptr->Url, HKEY("@"), 0); StrBufAppendBuf(cptr->Url, cptr->Host, 0); StrBufAppendBufPlain(cptr->Url, HKEY("/"), 0); StrBufUrlescAppend(cptr->Url, cptr->RoomName, NULL); ParseURL(&cptr->IO.ConnectMe, cptr->Url, 110); #if 0 /* todo: we need to reunite the url to be shure. */ pthread_mutex_lock(&POP3ueueMutex); GetHash(POP3FetchUrls, SKEY(ptr->Url), &vptr); use_this_cptr = (pop3aggr *)vptr; if (use_this_rncptr != NULL) { /* mustn't attach to an active session */ if (use_this_cptr->RefCount > 0) { DeletePOP3Cfg(cptr); /// Count->count--; } else { long *QRnumber; StrBufAppendBufPlain( use_this_cptr->rooms, qrbuf->QRname, -1, 0); if (use_this_cptr->roomlist_parts == 1) { use_this_cptr->OtherQRnumbers = NewHash(1, lFlathash); } QRnumber = (long*)malloc(sizeof(long)); *QRnumber = qrbuf->QRnumber; Put(use_this_cptr->OtherQRnumbers, LKEY(qrbuf->QRnumber), QRnumber, NULL); use_this_cptr->roomlist_parts++; } pthread_mutex_unlock(&POP3QueueMutex); continue; } pthread_mutex_unlock(&RSSQueueMutex); #endif cptr->n = Pop3ClientID++; pthread_mutex_lock(&POP3QueueMutex); Put(POP3FetchUrls, SKEY(cptr->Url), cptr, DeletePOP3Aggregator); pthread_mutex_unlock(&POP3QueueMutex); pLine = pLine->next; } }
/** * urlescape buffer and print it as header */ void hurlescputs(const char *strbuf) { StrBufUrlescAppend(WC->HBuf, NULL, strbuf); }
/* * Sanitize and enhance an HTML message for display. * Also convert weird character sets to UTF-8 if necessary. * Also fixup img src="cid:..." type inline images to fetch the image * */ void output_html(const char *supplied_charset, int treat_as_wiki, int msgnum, StrBuf *Source, StrBuf *Target) { char buf[SIZ]; char *msg; char *ptr; char *msgstart; char *msgend; StrBuf *converted_msg; int buffer_length = 1; int line_length = 0; int content_length = 0; char new_window[SIZ]; int brak = 0; int alevel = 0; int scriptlevel = 0; int script_start_pos = (-1); int i; int linklen; char charset[128]; StrBuf *BodyArea = NULL; #ifdef HAVE_ICONV iconv_t ic = (iconv_t)(-1) ; char *ibuf; /* Buffer of characters to be converted */ char *obuf; /* Buffer for converted characters */ size_t ibuflen; /* Length of input buffer */ size_t obuflen; /* Length of output buffer */ char *osav; /* Saved pointer to output buffer */ #endif if (Target == NULL) Target = WC->WBuf; safestrncpy(charset, supplied_charset, sizeof charset); msg = strdup(""); sprintf(new_window, "<a target=\"%s\" href=", TARGET); if (Source == NULL) while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { line_length = strlen(buf); buffer_length = content_length + line_length + 2; ptr = realloc(msg, buffer_length); if (ptr == NULL) { StrBufAppendPrintf(Target, "<b>"); StrBufAppendPrintf(Target, _("realloc() error! couldn't get %d bytes: %s"), buffer_length + 1, strerror(errno)); StrBufAppendPrintf(Target, "</b><br><br>\n"); while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { /** flush */ } free(msg); return; } msg = ptr; strcpy(&msg[content_length], buf); content_length += line_length; strcpy(&msg[content_length], "\n"); content_length += 1; } else { content_length = StrLength(Source); free(msg); msg = (char*) ChrPtr(Source);/* TODO: remove cast */ buffer_length = content_length; } /** Do a first pass to isolate the message body */ ptr = msg + 1; msgstart = msg; msgend = &msg[content_length]; while (ptr < msgend) { /** Advance to next tag */ ptr = strchr(ptr, '<'); if ((ptr == NULL) || (ptr >= msgend)) break; ++ptr; if ((ptr == NULL) || (ptr >= msgend)) break; /* * Look for META tags. Some messages (particularly in * Asian locales) illegally declare a message's character * set in the HTML instead of in the MIME headers. This * is wrong but we have to work around it anyway. */ if (!strncasecmp(ptr, "META", 4)) { char *meta_start; char *meta_end; int meta_length; char *meta; char *meta_http_equiv; char *meta_content; char *spaceptr; meta_start = &ptr[4]; meta_end = strchr(ptr, '>'); if ((meta_end != NULL) && (meta_end <= msgend)) { meta_length = meta_end - meta_start + 1; meta = malloc(meta_length + 1); safestrncpy(meta, meta_start, meta_length); meta[meta_length] = 0; striplt(meta); if (!strncasecmp(meta, "HTTP-EQUIV=", 11)) { meta_http_equiv = strdup(&meta[11]); spaceptr = strchr(meta_http_equiv, ' '); if (spaceptr != NULL) { *spaceptr = 0; meta_content = strdup(++spaceptr); if (!strncasecmp(meta_content, "content=", 8)) { strcpy(meta_content, &meta_content[8]); stripquotes(meta_http_equiv); stripquotes(meta_content); extract_charset_from_meta(charset, meta_http_equiv, meta_content); } free(meta_content); } free(meta_http_equiv); } free(meta); } } /* * Any of these tags cause everything up to and including * the tag to be removed. */ if ( (!strncasecmp(ptr, "HTML", 4)) ||(!strncasecmp(ptr, "HEAD", 4)) ||(!strncasecmp(ptr, "/HEAD", 5)) ||(!strncasecmp(ptr, "BODY", 4)) ) { char *pBody = NULL; if (!strncasecmp(ptr, "BODY", 4)) { pBody = ptr; } ptr = strchr(ptr, '>'); if ((ptr == NULL) || (ptr >= msgend)) break; if ((pBody != NULL) && (ptr - pBody > 4)) { char* src; char *cid_start, *cid_end; *ptr = '\0'; pBody += 4; while ((isspace(*pBody)) && (pBody < ptr)) pBody ++; BodyArea = NewStrBufPlain(NULL, ptr - pBody); if (pBody < ptr) { src = strstr(pBody, "cid:"); if (src) { cid_start = src + 4; cid_end = cid_start; while ((*cid_end != '"') && !isspace(*cid_end) && (cid_end < ptr)) cid_end ++; /* copy tag and attributes up to src="cid: */ StrBufAppendBufPlain(BodyArea, pBody, src - pBody, 0); /* add in /webcit/mimepart/<msgno>/CID/ trailing / stops dumb URL filters getting excited */ StrBufAppendPrintf(BodyArea, "/webcit/mimepart/%d/",msgnum); StrBufAppendBufPlain(BodyArea, cid_start, cid_end - cid_start, 0); if (ptr - cid_end > 0) StrBufAppendBufPlain(BodyArea, cid_end + 1, ptr - cid_end, 0); } else StrBufAppendBufPlain(BodyArea, pBody, ptr - pBody, 0); } *ptr = '>'; } ++ptr; if ((ptr == NULL) || (ptr >= msgend)) break; msgstart = ptr; } /* * Any of these tags cause everything including and following * the tag to be removed. */ if ( (!strncasecmp(ptr, "/HTML", 5)) ||(!strncasecmp(ptr, "/BODY", 5)) ) { --ptr; msgend = ptr; strcpy(ptr, ""); } ++ptr; } if (msgstart > msg) { strcpy(msg, msgstart); } /* Now go through the message, parsing tags as necessary. */ converted_msg = NewStrBufPlain(NULL, content_length + 8192); /** Convert foreign character sets to UTF-8 if necessary. */ #ifdef HAVE_ICONV if ( (strcasecmp(charset, "us-ascii")) && (strcasecmp(charset, "UTF-8")) && (strcasecmp(charset, "")) ) { syslog(LOG_DEBUG, "Converting %s to UTF-8\n", charset); ctdl_iconv_open("UTF-8", charset, &ic); if (ic == (iconv_t)(-1) ) { syslog(LOG_WARNING, "%s:%d iconv_open() failed: %s\n", __FILE__, __LINE__, strerror(errno)); } } if (Source == NULL) { if (ic != (iconv_t)(-1) ) { ibuf = msg; ibuflen = content_length; obuflen = content_length + (content_length / 2) ; obuf = (char *) malloc(obuflen); osav = obuf; iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen); content_length = content_length + (content_length / 2) - obuflen; osav[content_length] = 0; free(msg); msg = osav; iconv_close(ic); } } else { if (ic != (iconv_t)(-1) ) { StrBuf *Buf = NewStrBufPlain(NULL, StrLength(Source) + 8096);; StrBufConvert(Source, Buf, &ic); FreeStrBuf(&Buf); iconv_close(ic); msg = (char*)ChrPtr(Source); /* TODO: get rid of this. */ } } #endif /* * At this point, the message has been stripped down to * only the content inside the <BODY></BODY> tags, and has * been converted to UTF-8 if it was originally in a foreign * character set. The text is also guaranteed to be null * terminated now. */ if (converted_msg == NULL) { StrBufAppendPrintf(Target, "Error %d: %s<br>%s:%d", errno, strerror(errno), __FILE__, __LINE__); goto BAIL; } if (BodyArea != NULL) { StrBufAppendBufPlain(converted_msg, HKEY("<table "), 0); StrBufAppendBuf(converted_msg, BodyArea, 0); StrBufAppendBufPlain(converted_msg, HKEY(" width=\"100%\"><tr><td>"), 0); } ptr = msg; msgend = strchr(msg, 0); while (ptr < msgend) { /** Try to sanitize the html of any rogue scripts */ if (!strncasecmp(ptr, "<script", 7)) { if (scriptlevel == 0) { script_start_pos = StrLength(converted_msg); } ++scriptlevel; } if (!strncasecmp(ptr, "</script", 8)) { --scriptlevel; } /** * Change mailto: links to WebCit mail, by replacing the * link with one that points back to our mail room. Due to * the way we parse URL's, it'll even handle mailto: links * that have "?subject=" in them. */ if (!strncasecmp(ptr, "<a href=\"mailto:", 16)) { content_length += 64; StrBufAppendPrintf(converted_msg, "<a href=\"display_enter?force_room=_MAIL_?recp="); ptr = &ptr[16]; ++alevel; ++brak; } /** Make external links open in a separate window */ else if (!strncasecmp(ptr, "<a href=\"", 9)) { ++alevel; ++brak; if ( ((strchr(ptr, ':') < strchr(ptr, '/'))) && ((strchr(ptr, '/') < strchr(ptr, '>'))) ) { /* open external links to new window */ StrBufAppendPrintf(converted_msg, new_window); ptr = &ptr[8]; } else if ( (treat_as_wiki) && (strncasecmp(ptr, "<a href=\"wiki?", 14)) && (strncasecmp(ptr, "<a href=\"dotgoto?", 17)) && (strncasecmp(ptr, "<a href=\"knrooms?", 17)) ) { content_length += 64; StrBufAppendPrintf(converted_msg, "<a href=\"wiki?go="); StrBufUrlescAppend(converted_msg, WC->CurRoom.name, NULL); StrBufAppendPrintf(converted_msg, "?page="); ptr = &ptr[9]; } else { StrBufAppendPrintf(converted_msg, "<a href=\""); ptr = &ptr[9]; } } /** Fixup <img src="cid:... ...> to fetch the mime part */ else if (!strncasecmp(ptr, "<img ", 5)) { char *cid_start, *cid_end; char* tag_end=strchr(ptr,'>'); char* src; /* FIXME - handle this situation (maybe someone opened an <img cid... * and then ended the message) */ if (!tag_end) { syslog(LOG_DEBUG, "tag_end is null and ptr is:\n"); syslog(LOG_DEBUG, "%s\n", ptr); syslog(LOG_DEBUG, "Theoretical bytes remaining: %d\n", (int)(msgend - ptr)); } src=strstr(ptr, "src=\"cid:"); ++brak; if (src && isspace(*(src-1)) && tag_end && (cid_start=strchr(src,':')) && (cid_end=strchr(cid_start,'"')) && (cid_end < tag_end) ) { /* copy tag and attributes up to src="cid: */ StrBufAppendBufPlain(converted_msg, ptr, src - ptr, 0); cid_start++; /* add in /webcit/mimepart/<msgno>/CID/ trailing / stops dumb URL filters getting excited */ StrBufAppendPrintf(converted_msg, " src=\"/webcit/mimepart/%d/",msgnum); StrBufAppendBufPlain(converted_msg, cid_start, cid_end - cid_start, 0); StrBufAppendBufPlain(converted_msg, "/\"", -1, 0); ptr = cid_end+1; } StrBufAppendBufPlain(converted_msg, ptr, tag_end - ptr, 0); ptr = tag_end; } /** * Turn anything that looks like a URL into a real link, as long * as it's not inside a tag already */ else if ( (brak == 0) && (alevel == 0) && ( (!strncasecmp(ptr, "http://", 7)) || (!strncasecmp(ptr, "https://", 8)))) { /** Find the end of the link */ int strlenptr; linklen = 0; strlenptr = strlen(ptr); for (i=0; i<=strlenptr; ++i) { if ((ptr[i]==0) ||(isspace(ptr[i])) ||(ptr[i]==10) ||(ptr[i]==13) ||(ptr[i]=='(') ||(ptr[i]==')') ||(ptr[i]=='<') ||(ptr[i]=='>') ||(ptr[i]=='[') ||(ptr[i]==']') ||(ptr[i]=='"') ||(ptr[i]=='\'') ) linklen = i; /* did s.b. send us an entity? */ if (ptr[i] == '&') { if ((ptr[i+2] ==';') || (ptr[i+3] ==';') || (ptr[i+5] ==';') || (ptr[i+6] ==';') || (ptr[i+7] ==';')) linklen = i; } if (linklen > 0) break; } if (linklen > 0) { char *ltreviewptr; char *nbspreviewptr; char linkedchar; int len; len = linklen; linkedchar = ptr[len]; ptr[len] = '\0'; /* spot for some subject strings tinymce tends to give us. */ ltreviewptr = strchr(ptr, '<'); if (ltreviewptr != NULL) { *ltreviewptr = '\0'; linklen = ltreviewptr - ptr; } nbspreviewptr = strstr(ptr, " "); if (nbspreviewptr != NULL) { /* nbspreviewptr = '\0'; */ linklen = nbspreviewptr - ptr; } if (ltreviewptr != 0) *ltreviewptr = '<'; ptr[len] = linkedchar; content_length += (32 + linklen); StrBufAppendPrintf(converted_msg, "%s\"", new_window); StrBufAppendBufPlain(converted_msg, ptr, linklen, 0); StrBufAppendPrintf(converted_msg, "\">"); StrBufAppendBufPlain(converted_msg, ptr, linklen, 0); ptr += linklen; StrBufAppendPrintf(converted_msg, "</A>"); } } else { StrBufAppendBufPlain(converted_msg, ptr, 1, 0); ptr++; } if ((ptr >= msg) && (ptr <= msgend)) { /* * We need to know when we're inside a tag, * so we don't turn things that look like URL's into * links, when they're already links - or image sources. */ if ((ptr > msg) && (*(ptr-1) == '<')) { ++brak; } if ((ptr > msg) && (*(ptr-1) == '>')) { --brak; if ((scriptlevel == 0) && (script_start_pos >= 0)) { StrBufCutRight(converted_msg, StrLength(converted_msg) - script_start_pos); script_start_pos = (-1); } } if (!strncasecmp(ptr, "</A>", 3)) --alevel; } } if (BodyArea != NULL) { StrBufAppendBufPlain(converted_msg, HKEY("</td></tr></table>"), 0); FreeStrBuf(&BodyArea); } /** uncomment these two lines to override conversion */ /** memcpy(converted_msg, msg, content_length); */ /** output_length = content_length; */ /** Output our big pile of markup */ StrBufAppendBuf(Target, converted_msg, 0); BAIL: /** A little trailing vertical whitespace... */ StrBufAppendPrintf(Target, "<br><br>\n"); /** Now give back the memory */ FreeStrBuf(&converted_msg); if ((msg != NULL) && (Source == NULL)) free(msg); }