static void testReduce(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr, const char *tst) { xmlBufferPtr xmlExpBuf; xmlExpNodePtr sub, deriv; xmlExpBuf = xmlBufferCreate(); sub = xmlExpParse(ctxt, tst); if (sub == NULL) { printf("Subset %s failed to parse\n", tst); return; } xmlExpDump(xmlExpBuf, sub); printf("Subset parsed as: %s\n", (const char *) xmlBufferContent(xmlExpBuf)); deriv = xmlExpExpDerive(ctxt, expr, sub); if (deriv == NULL) { printf("Derivation led to an internal error, report this !\n"); return; } else { xmlBufferEmpty(xmlExpBuf); xmlExpDump(xmlExpBuf, deriv); if (xmlExpIsNillable(deriv)) printf("Resulting nillable derivation: %s\n", (const char *) xmlBufferContent(xmlExpBuf)); else printf("Resulting derivation: %s\n", (const char *) xmlBufferContent(xmlExpBuf)); xmlExpFree(ctxt, deriv); } xmlExpFree(ctxt, sub); }
Variant c_XMLWriter::t_flush(bool empty /* = true */) { if (m_ptr && m_output) { xmlTextWriterFlush(m_ptr); String ret((char*)m_output->content, CopyString); if (empty) { xmlBufferEmpty(m_output); } return ret; } return ""; }
Variant c_XMLWriter::t_flush(bool empty /* = true */) { INSTANCE_METHOD_INJECTION_BUILTIN(XMLWriter, XMLWriter::flush); if (m_ptr && m_output) { xmlTextWriterFlush(m_ptr); String ret((char*)m_output->content, CopyString); if (empty) { xmlBufferEmpty(m_output); } return ret; } return ""; }
/* Fall through . . */ case 107: if (tolower (ch) == 'h') { state = 1; start = n; } else state = ST_INITIAL; break; case ST_START_FOUND: if (isspace ((int) ((unsigned char) ch)) || (ch == '"') || (ch == '>')) { end = n; state = ST_END_FOUND; } break; } # undef CHK # undef CCHK } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } else state = ST_INITIAL; } n += clen; } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } ++n; } if (state == ST_END_FOUND) { int ulen, m, o; ulen = end - start; for (m = 0; m < blockmail -> url_count; ++m) if ((blockmail -> url[m] -> usage & mask) && (blockmail -> url[m] -> dlen == ulen) && (! xmlStrncmp (blockmail -> url[m] -> dptr, cont + start, ulen))) break; if (m < blockmail -> url_count) { if (lstore < start) xmlBufferAdd (block -> out, cont + lstore, start - lstore); for (o = 0; o < rec -> url_count; ++o) if (rec -> url[o] -> uid == blockmail -> url[m] -> uid) break; if (o < rec -> url_count) xmlBufferAdd (block -> out, rec -> url[o] -> dptr, rec -> url[o] -> dlen); lstore = end; changed = true; } state = ST_INITIAL; } } if (changed) { if (lstore < len) xmlBufferAdd (block -> out, cont + lstore, len - lstore); SWAP (block); } return true; }/*}}}*/ static bool_t collect_links (blockmail_t *blockmail, block_t *block, links_t *links) /*{{{*/ { bool_t rc; int n, clen; int len; const xmlChar *cont; int start; rc = true; len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); for (n = 0; rc && (n < len); ) { clen = xmlCharLength (cont[n]); if ((clen == 1) && (cont[n] == 'h')) { start = n; ++n; if ((n + 3 < len) && (cont[n] == 't') && (cont[n + 1] == 't') && (cont[n + 2] == 'p')) { n += 3; if ((n + 1 < len) && (cont[n] == 's')) ++n; if ((n + 3 < len) && (cont[n] == ':') && (cont[n + 1] == '/') && (cont[n + 2] == '/')) { n += 3; while ((n < len) && (xmlCharLength (cont[n]) == 1) && (cont[n] != '"') && (cont[n] != '<') && (cont[n] != '>') && (! isspace (cont[n]))) ++n; rc = links_nadd (links, (const char *) (cont + start), n - start); } } } else n += clen; } return rc; }/*}}}*/ static int find_top (const xmlChar *cont, int len) /*{{{*/ { int pos; int state; int n; int clen; unsigned char ch; for (pos = -1, state = 0, n = 0; (n < len) && (pos == -1); ) { clen = xmlCharLength (cont[n]); if (clen > 1) state = 0; else { ch = cont[n]; switch (state) { case 0: if (ch == '<') state = 1; break; case 1: if ((ch == 'b') || (ch == 'B')) state = 2; else if (ch == '>') state = 0; else if (! isspace (ch)) state = 100; break; case 2: if ((ch == 'o') || (ch == 'O')) state = 3; else if (ch == '>') state = 0; else state = 100; break; case 3: if ((ch == 'd') || (ch == 'D')) state = 4; else if (ch == '>') state = 0; else state = 100; break; case 4: if ((ch == 'y') || (ch == 'Y')) state = 5; else if (ch == '>') state = 0; else state = 100; break; case 5: if (ch == '>') { pos = n + clen; state = 0; } else if (isspace (ch)) state = 6; else state = 100; break; case 6: if (ch == '>') { pos = n + clen; state = 0; } # ifdef STRICT else if (ch == '"') state = 7; break; case 7: if (ch == '"') state = 6; # endif /* STRICT */ break; case 100: if (ch == '>') state = 0; break; } } n += clen; } return pos; }/*}}}*/ static int find_bottom (const xmlChar *cont, int len) /*{{{*/ { int pos; int last; int m; int bclen; for (pos = -1, last = len, m = len - 1; (m >= 0) && (pos == -1); ) { bclen = xmlCharLength (cont[m]); if ((bclen == 1) && (cont[m] == '<')) { int n; int state; int clen; unsigned char ch; for (n = m + bclen, state = 1; (n < last) && (state > 0) && (state != 99); ) { clen = xmlCharLength (cont[n]); if (clen != 1) state = 0; else { ch = cont[n]; switch (state) { case 1: if (ch == '/') state = 2; else if (! isspace (ch)) state = 0; break; case 2: if ((ch == 'b') || (ch == 'B')) state = 3; else if (! isspace (ch)) state = 0; break; case 3: if ((ch == 'o') || (ch == 'O')) state = 4; else state = 0; break; case 4: if ((ch == 'd') || (ch == 'D')) state = 5; else state = 0; break; case 5: if ((ch == 'y') || (ch == 'Y')) state = 6; else state = 0; break; case 6: if ((ch == '>') || isspace (ch)) state = 99; else state = 0; break; } } n += clen; } if (state == 99) pos = m; } else if ((bclen == 1) && (cont[m] == '>')) last = m + bclen; m -= bclen; } return pos; }/*}}}*/ static bool_t add_onepixellog_image (blockmail_t *blockmail, receiver_t *rec, block_t *block, opl_t opl) /*{{{*/ { bool_t rc; const xmlChar tname[] = "[agnONEPIXEL]"; int tlen = sizeof (tname) - 1; tag_t *opltag; rc = true; for (opltag = rec -> tag; opltag; opltag = opltag -> next) if (tag_match (opltag, tname, tlen)) break; if (opltag && opltag -> value) { int pos; int len; const xmlChar *cont; pos = -1; len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); switch (opl) { case OPL_None: break; case OPL_Top: pos = find_top (cont, len); if (pos == -1) pos = 0; break; case OPL_Bottom: pos = find_bottom (cont, len); if (pos == -1) pos = len; break; } if (pos != -1) { const xmlChar lprefix[] = "<img src=\""; const xmlChar lpostfix[] = "\" alt=\"\" border=\"0\" height=\"1\" width=\"1\">"; xmlBufferEmpty (block -> out); if (pos > 0) xmlBufferAdd (block -> out, cont, pos); xmlBufferAdd (block -> out, lprefix, sizeof (lprefix) - 1); xmlBufferAdd (block -> out, xmlBufferContent (opltag -> value), xmlBufferLength (opltag -> value)); xmlBufferAdd (block -> out, lpostfix, sizeof (lpostfix) - 1); if (pos < len) xmlBufferAdd (block -> out, cont + pos, len - pos); SWAP (block); } } return rc; }/*}}}*/
std::string rss_parser::get_xml_content(xmlNode * node) { xmlBufferPtr buf = xmlBufferCreate(); std::string result; if (node->children) { for (xmlNodePtr ptr = node->children; ptr != NULL; ptr = ptr->next) { if (xmlNodeDump(buf, doc, ptr, 0, 0) >= 0) { result.append((const char *)xmlBufferContent(buf)); xmlBufferEmpty(buf); } else { result.append(get_content(ptr)); } } } else { result = get_content(node); // fallback } xmlBufferFree(buf); return result; }
static void exprDebug(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr) { xmlBufferPtr xmlExpBuf; xmlExpNodePtr deriv; const char *list[40]; int ret; xmlExpBuf = xmlBufferCreate(); if (expr == NULL) { printf("Failed to parse\n"); return; } xmlExpDump(xmlExpBuf, expr); printf("Parsed as: %s\n", (const char *) xmlBufferContent(xmlExpBuf)); printf("Max token input = %d\n", xmlExpMaxToken(expr)); if (xmlExpIsNillable(expr) == 1) printf("Is nillable\n"); ret = xmlExpGetLanguage(ctxt, expr, (const xmlChar **) &list[0], 40); if (ret < 0) printf("Failed to get list: %d\n", ret); else { int i; printf("Language has %d strings, testing string derivations\n", ret); for (i = 0;i < ret;i++) { deriv = xmlExpStringDerive(ctxt, expr, BAD_CAST list[i], -1); if (deriv == NULL) { printf(" %s -> derivation failed\n", list[i]); } else { xmlBufferEmpty(xmlExpBuf); xmlExpDump(xmlExpBuf, deriv); printf(" %s -> %s\n", list[i], (const char *) xmlBufferContent(xmlExpBuf)); } xmlExpFree(ctxt, deriv); } } xmlBufferFree(xmlExpBuf); }
void PrintNodeSet(xmlNodeSetPtr nodeSet) { xmlBufferPtr buf = xmlBufferCreate(); for ( int i = 0; i < nodeSet->nodeNr; i++ ) { xmlNodePtr node = nodeSet->nodeTab[i]; fprintf(stderr, "Node %02d: ", i); if ( node == nullptr ) { fprintf(stderr, "[nullptr]"); } else { xmlNodeDump(buf, node->doc, node, 0, 0); fprintf(stderr, "%s", reinterpret_cast<const char*>(xmlBufferContent(buf))); xmlBufferEmpty(buf); } fprintf(stderr, "\n"); } xmlBufferFree(buf); }
/*}}}*/ }; static int psize = sizeof (parseable) / sizeof (parseable[0]); tag_t * tag_alloc (void) /*{{{*/ { tag_t *t; if (t = (tag_t *) malloc (sizeof (tag_t))) { t -> name = xmlBufferCreate (); t -> cname = NULL; t -> hash = 0; t -> type = NULL; t -> topt = NULL; t -> value = xmlBufferCreate (); t -> parm = NULL; t -> used = false; t -> next = NULL; if ((! t -> name) || (! t -> value)) t = tag_free (t); } return t; }/*}}}*/ tag_t * tag_free (tag_t *t) /*{{{*/ { if (t) { if (t -> name) xmlBufferFree (t -> name); if (t -> cname) free (t -> cname); if (t -> type) free (t -> type); if (t -> value) xmlBufferFree (t -> value); if (t -> parm) var_free_all (t -> parm); free (t); } return NULL; }/*}}}*/ tag_t * tag_free_all (tag_t *t) /*{{{*/ { tag_t *tmp; while (tmp = t) { t = t -> next; tag_free (tmp); } return NULL; }/*}}}*/ static void xmlSkip (xmlChar **ptr, int *len) /*{{{*/ { int n; while (*len > 0) { n = xmlCharLength (**ptr); if ((n == 1) && isspace (**ptr)) { *(*ptr)++ = '\0'; *len -= 1; while ((*len > 0) && (xmlCharLength (**ptr) == 1) && isspace (**ptr)) ++(*ptr); break; } else { *ptr += n; *len -= n; } } }/*}}}*/ static int mkRFCdate (char *dbuf, size_t dlen) /*{{{*/ { time_t now; struct tm *tt; time (& now); if (tt = gmtime (& now)) { const char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; return sprintf (dbuf, "%s, %2d %s %d %02d:%02d:%02d GMT", weekday[tt -> tm_wday], tt -> tm_mday, month[tt -> tm_mon], tt -> tm_year + 1900, tt -> tm_hour, tt -> tm_min, tt -> tm_sec) > 0; } return 0; }/*}}}*/ static const char * find_default (tag_t *t) /*{{{*/ { const char *dflt = NULL; var_t *run; for (run = t -> parm; run; run = run -> next) if (! strcmp (run -> var, "default")) { dflt = run -> val; break; } return dflt; }/*}}}*/ void tag_parse (tag_t *t, blockmail_t *blockmail) /*{{{*/ { xmlBufferPtr temp; if (t -> name && (xmlBufferLength (t -> name) > 0) && (temp = xmlBufferCreateSize (xmlBufferLength (t -> name) + 1))) { xmlChar *ptr; xmlChar *name; int len; int tid; xmlBufferAdd (temp, xmlBufferContent (t -> name), xmlBufferLength (t -> name)); ptr = (xmlChar *) xmlBufferContent (temp); len = xmlBufferLength (temp); if ((xmlCharLength (*ptr) == 1) && (*ptr == '[')) { ++ptr; --len; if ((len > 0) && (xmlStrictCharLength (*(ptr + len - 1)) == 1) && (*(ptr + len - 1) == ']')) { --len; if ((len > 0) && (xmlStrictCharLength (*(ptr + len - 1)) == 1) && (*(ptr + len - 1) == '/')) --len; ptr[len] = '\0'; } } name = ptr; xmlSkip (& ptr, & len); if (t -> type) { for (tid = 0; tid < psize; ++tid) if (! strcmp (t -> type, parseable[tid].tname)) break; } else tid = psize; if (tid == psize) for (tid = 0; tid < psize; ++tid) if (! xmlstrcmp (name, parseable[tid].tname)) break; if (tid < psize) { var_t *cur, *prev; xmlChar *var, *val; int n; for (prev = t -> parm; prev && prev -> next; prev = prev -> next) ; while (len > 0) { var = ptr; while (len > 0) { n = xmlCharLength (*ptr); if ((n == 1) && (*ptr == '=')) { *ptr++ = '\0'; len -= 1; break; } else { ptr += n; len -= n; } } if (len > 0) { if ((xmlCharLength (*ptr) == 1) && (*ptr == '"')) { ++ptr; --len; val = ptr; while (len > 0) { n = xmlCharLength (*ptr); if ((n == 1) && (*ptr == '"')) { *ptr++ = '\0'; len -= 1; xmlSkip (& ptr, & len); break; } else { ptr += n; len -= n; } } } else { val = ptr; xmlSkip (& ptr, & len); } if (cur = var_alloc (xml2char (var), xml2char (val))) { if (prev) prev -> next = cur; else t -> parm = cur; prev = cur; } } } switch ((enum PType) tid) { case P_Sysinfo: for (cur = t -> parm; cur; cur = cur -> next) if (! strcmp (cur -> var, "name")) { if (! strcmp (cur -> val, "FQDN")) { const char *dflt; if (blockmail -> fqdn) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, blockmail -> fqdn); } else if (dflt = find_default (t)) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dflt); } } else if (! strcmp (cur -> val, "RFCDATE")) { char dbuf[128]; if (mkRFCdate (dbuf, sizeof (dbuf))) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dbuf); } } else if (! strcmp (cur -> val, "EPOCH")) { time_t now; char dbuf[64]; time (& now); sprintf (dbuf, "%ld", (long) now); xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dbuf); } } break; } } xmlBufferFree (temp); } }/*}}}*/
/********************************************************************************* * The contents of this file are subject to the Common Public Attribution * License Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.openemm.org/cpal1.html. The License is based on the Mozilla * Public License Version 1.1 but Sections 14 and 15 have been added to cover * use of software over a computer network and provide for limited attribution * for the Original Developer. In addition, Exhibit A has been modified to be * consistent with Exhibit B. * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is OpenEMM. * The Original Developer is the Initial Developer. * The Initial Developer of the Original Code is AGNITAS AG. All portions of * the code written by AGNITAS AG are Copyright (c) 2007 AGNITAS AG. All Rights * Reserved. * * Contributor(s): AGNITAS AG. ********************************************************************************/ # include "xmlback.h" static bool_t expand_tags (tag_t *base) /*{{{*/ { bool_t st; tag_t *cur, *tmp; const xmlChar *ptr; int len; int n, pos; int bstart; xmlBufferPtr out; st = true; for (cur = base; cur; cur = cur -> next) { for (tmp = base; tmp; tmp = tmp -> next) tmp -> used = (tmp == cur ? true : false); ptr = xmlBufferContent (cur -> value); len = xmlBufferLength (cur -> value); pos = 0; bstart = 0; out = NULL; while (pos < len) { n = xmlCharLength (ptr[pos]); if ((n == 1) && (ptr[pos] == '[')) { int start, end; start = pos++; end = -1; while (pos < len) { n = xmlCharLength (ptr[pos]); if ((n == 1) && (ptr[pos] == ']')) { ++pos; end = pos; break; } pos += n; } if (end != -1) { for (tmp = base; tmp; tmp = tmp -> next) if ((! tmp -> used) && tag_match (tmp, ptr + start, end - start)) break; if (tmp) { if (! out) if (! (out = xmlBufferCreate ())) { st = false; break; } if (bstart < start) xmlBufferAdd (out, ptr + bstart, start - bstart); xmlBufferAdd (out, xmlBufferContent (tmp -> value), xmlBufferLength (tmp -> value)); tmp -> used = true; bstart = pos; } } } else pos += n; } if (out) { if (bstart < len) xmlBufferAdd (out, ptr + bstart, len - bstart); xmlBufferFree (cur -> value); cur -> value = out; } } return st; }/*}}}*/ bool_t replace_tags (blockmail_t *blockmail, receiver_t *rec, block_t *block, bool_t ishtml) /*{{{*/ { bool_t st; long start, cur, next, end, len; const xmlChar *content; int tidx; tagpos_t *tp; int n; tag_t *tag; st = expand_tags (rec -> tag); start = 0; end = xmlBufferLength (block -> content); content = xmlBufferContent (block -> content); xmlBufferEmpty (block -> in); for (cur = start, tidx = 0; cur < end; ) { if (tidx < block -> tagpos_count) { tp = block -> tagpos[tidx++]; next = tp -> start; } else { tp = NULL; next = end; } len = next - cur; if (len > 0) xmlBufferAdd (block -> in, content + cur, len); if (tp) { cur = tp -> end; tag = NULL; if (tp -> type & (TP_DYNAMIC | TP_DYNAMICVALUE)) { if (tp -> tname) { dcache_t *dc; const dyn_t *dyn; for (dc = rec -> cache; dc; dc = dc -> next) if (! strcmp (dc -> name, tp -> tname)) break; if (! dc) for (dyn = blockmail -> dyn; dyn; dyn = dyn -> next) if (! strcmp (dyn -> name, tp -> tname)) { if (dc = dcache_alloc (tp -> tname, dyn)) { dc -> next = rec -> cache; rec -> cache = dc; } break; } if (dc) { for (dyn = dc -> dyn; dyn; dyn = dyn -> sibling) if (dyn_match (dyn, blockmail -> eval)) break; if (dyn) { block_t *use; use = NULL; if (tp -> type & TP_DYNAMICVALUE) { for (n = 0; (! use) && (n < dyn -> block_count); ++n) switch (dyn -> block[n] -> nr) { case 0: if (! ishtml) use = dyn -> block[n]; break; case 1: if (ishtml) use = dyn -> block[n]; break; } } else if (tp -> type & TP_DYNAMIC) use = tp -> content; if (use) if (replace_tags (blockmail, rec, use, ishtml)) xmlBufferAdd (block -> in, xmlBufferContent (use -> in), xmlBufferLength (use -> in)); else st = false; } } } } else { for (n = 0; (n < 2) && (! tag); ++n) { for (tag = n ? blockmail -> gtag : rec -> tag; tag; tag = tag -> next) if (((tag -> hash == 0) || (tp -> hash == 0) || (tag -> hash == tp -> hash)) && (xmlEqual (tag -> name, tp -> name))) break; } } if (tag && ((n = xmlBufferLength (tag -> value)) > 0)) xmlBufferAdd (block -> in, xmlBufferContent (tag -> value), n); } else cur = next; } return st; }/*}}}*/
str BATXMLcontent(bat *ret, const bat *bid) { BAT *b, *bn; BUN p, q; BATiter bi; xmlDocPtr doc; xmlNodePtr root; size_t size = BUFSIZ; str buf = GDKmalloc(size); const char *err = OPERATION_FAILED; xmlBufferPtr xbuf; if (buf == NULL) throw(MAL,"xml.content",MAL_MALLOC_FAIL); if ((b = BATdescriptor(*bid)) == NULL) { GDKfree(buf); throw(MAL, "xml.content", INTERNAL_BAT_ACCESS); } doc = xmlParseMemory("<doc/>", 6); root = xmlDocGetRootElement(doc); prepareResult(bn, b, TYPE_xml, "content", GDKfree(buf)); bi = bat_iterator(b); xbuf = xmlBufferCreate(); BATloop(b, p, q) { const char *t = (const char *) BUNtail(bi, p); size_t len; xmlNodePtr elem; xmlParserErrors xerr; const xmlChar *s; if (strNil(t)) { bunfastapp(bn, str_nil); bn->T->nonil = 0; continue; } len = strlen(t); xerr = xmlParseInNodeContext(root, t, (int) len, 0, &elem); if (xerr != XML_ERR_OK) { err = XML_PARSE_ERROR; goto bunins_failed; } xmlNodeDump(xbuf, doc, elem, 0, 0); s = xmlBufferContent(xbuf); len = strlen((const char *) s); if (len + 2 >= size) { GDKfree(buf); size = len + 128; buf = GDKmalloc(size); if (buf == NULL) { err = MAL_MALLOC_FAIL; goto bunins_failed; } } buf[0] = 'C'; strcpy(buf + 1, (const char *) s); bunfastapp(bn, buf); xmlBufferEmpty(xbuf); xmlFreeNodeList(elem); } xmlBufferFree(xbuf); xmlFreeDoc(doc); GDKfree(buf); finalizeResult(ret, bn, b); return MAL_SUCCEED; bunins_failed: xmlBufferFree(xbuf); xmlFreeDoc(doc); if (buf != NULL) GDKfree(buf); BBPunfix(b->batCacheid); BBPunfix(bn->batCacheid); throw(MAL, "xml.document", "%s", err); }
/* Fall through . . */ case 107: if (tolower (ch) == 'h') { state = 1; start = n; } else state = ST_INITIAL; break; case ST_START_FOUND: if (isspace ((int) ((unsigned char) ch)) || (ch == '"') || (ch == '>')) { end = n; state = ST_END_FOUND; } break; } # undef CHK # undef CCHK } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } else state = ST_INITIAL; } n += clen; } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } ++n; } if (state == ST_END_FOUND) { int ulen, m, o; ulen = end - start; for (m = 0; m < blockmail -> url_count; ++m) if ((blockmail -> url[m] -> usage & mask) && (blockmail -> url[m] -> dlen == ulen) && (! xmlStrncmp (blockmail -> url[m] -> dptr, cont + start, ulen))) break; if (m < blockmail -> url_count) { if (lstore < start) xmlBufferAdd (block -> out, cont + lstore, start - lstore); for (o = 0; o < rec -> url_count; ++o) if (rec -> url[o] -> uid == blockmail -> url[m] -> uid) break; if (o < rec -> url_count) xmlBufferAdd (block -> out, rec -> url[o] -> dptr, rec -> url[o] -> dlen); lstore = end; changed = true; } state = ST_INITIAL; } } if (changed) { if (lstore < len) xmlBufferAdd (block -> out, cont + lstore, len - lstore); SWAP (block); } return true; }/*}}}*/ static bool_t collect_links (blockmail_t *blockmail, block_t *block, links_t *links) /*{{{*/ { bool_t rc; int n, clen; int len; const xmlChar *cont; int start; rc = true; len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); for (n = 0; rc && (n < len); ) { clen = xmlCharLength (cont[n]); if ((clen == 1) && (cont[n] == 'h')) { start = n; ++n; if ((n + 3 < len) && (cont[n] == 't') && (cont[n + 1] == 't') && (cont[n + 2] == 'p')) { n += 3; if ((n + 1 < len) && (cont[n] == 's')) ++n; if ((n + 3 < len) && (cont[n] == ':') && (cont[n + 1] == '/') && (cont[n + 2] == '/')) { n += 3; while ((n < len) && (xmlCharLength (cont[n]) == 1) && (cont[n] != '"') && (cont[n] != '<') && (cont[n] != '>') && (! isspace (cont[n]))) ++n; rc = links_nadd (links, (const char *) (cont + start), n - start); } } } else n += clen; } return rc; }/*}}}*/ static int find_top (const xmlChar *cont, int len) /*{{{*/ { int pos; int state; int n; int clen; unsigned char ch; for (pos = -1, state = 0, n = 0; (n < len) && (pos == -1); ) { clen = xmlCharLength (cont[n]); if (clen > 1) state = 0; else { ch = cont[n]; switch (state) { case 0: if (ch == '<') state = 1; break; case 1: if ((ch == 'b') || (ch == 'B')) state = 2; else if (ch == '>') state = 0; else if (! isspace (ch)) state = 100; break; case 2: if ((ch == 'o') || (ch == 'O')) state = 3; else if (ch == '>') state = 0; else state = 100; break; case 3: if ((ch == 'd') || (ch == 'D')) state = 4; else if (ch == '>') state = 0; else state = 100; break; case 4: if ((ch == 'y') || (ch == 'Y')) state = 5; else if (ch == '>') state = 0; else state = 100; break; case 5: if (ch == '>') { pos = n + clen; state = 0; } else if (isspace (ch)) state = 6; else state = 100; break; case 6: if (ch == '>') { pos = n + clen; state = 0; } # ifdef STRICT else if (ch == '"') state = 7; break; case 7: if (ch == '"') state = 6; # endif /* STRICT */ break; case 100: if (ch == '>') state = 0; break; } } n += clen; } return pos; }/*}}}*/ static int find_bottom (const xmlChar *cont, int len) /*{{{*/ { int pos; int last; int m; int bclen; for (pos = -1, last = len, m = len - 1; (m >= 0) && (pos == -1); ) { bclen = xmlCharLength (cont[m]); if ((bclen == 1) && (cont[m] == '<')) { int n; int state; int clen; unsigned char ch; for (n = m + bclen, state = 1; (n < last) && (state > 0) && (state != 99); ) { clen = xmlCharLength (cont[n]); if (clen != 1) state = 0; else { ch = cont[n]; switch (state) { case 1: if (ch == '/') state = 2; else if (! isspace (ch)) state = 0; break; case 2: if ((ch == 'b') || (ch == 'B')) state = 3; else if (! isspace (ch)) state = 0; break; case 3: if ((ch == 'o') || (ch == 'O')) state = 4; else state = 0; break; case 4: if ((ch == 'd') || (ch == 'D')) state = 5; else state = 0; break; case 5: if ((ch == 'y') || (ch == 'Y')) state = 6; else state = 0; break; case 6: if ((ch == '>') || isspace (ch)) state = 99; else state = 0; break; } } n += clen; } if (state == 99) pos = m; } else if ((bclen == 1) && (cont[m] == '>')) last = m + bclen; m -= bclen; } return pos; }/*}}}*/ static bool_t add_onepixellog_image (blockmail_t *blockmail, receiver_t *rec, block_t *block, opl_t opl) /*{{{*/ { bool_t rc; const xmlChar tname[] = "[agnONEPIXEL]"; int tlen = sizeof (tname) - 1; tag_t *opltag; rc = true; for (opltag = rec -> tag; opltag; opltag = opltag -> next) if (tag_match (opltag, tname, tlen)) break; if (opltag && opltag -> value) { int pos; int len; const xmlChar *cont; pos = -1; len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); switch (opl) { case OPL_None: break; case OPL_Top: pos = find_top (cont, len); if (pos == -1) pos = 0; break; case OPL_Bottom: pos = find_bottom (cont, len); if (pos == -1) pos = len; break; } if (pos != -1) { const xmlChar lprefix[] = "<img src=\""; const xmlChar lpostfix[] = "\" alt=\"\" border=\"0\" height=\"1\" width=\"1\">"; xmlBufferEmpty (block -> out); if (pos > 0) xmlBufferAdd (block -> out, cont, pos); xmlBufferAdd (block -> out, lprefix, sizeof (lprefix) - 1); xmlBufferAdd (block -> out, xmlBufferContent (opltag -> value), xmlBufferLength (opltag -> value)); xmlBufferAdd (block -> out, lpostfix, sizeof (lpostfix) - 1); if (pos < len) xmlBufferAdd (block -> out, cont + pos, len - pos); SWAP (block); } } return rc; }/*}}}*/ static # ifdef __OPTIMIZE__ inline # endif /* __OPTIMIZE__ */ bool_t islink (const xmlChar *str, int len) /*{{{*/ { int n, state, clen; for (n = 0, state = 1; (n < len) && state; ) { clen = xmlCharLength (str[n]); if (clen != 1) return false; switch (state) { default: /* should NEVER happen */ return false; case 1: /* check for http:// https:// and mailto: */ if ((str[n] == 'h') || (str[n] == 'H')) ++state; else if ((str[n] == 'm') || (str[n] == 'M')) state = 100; else return false; break; case 2: if ((str[n] == 't') || (str[n] == 'T')) ++state; else return false; break; case 3: if ((str[n] == 't') || (str[n] == 'T')) ++state; else return false; break; case 4: if ((str[n] == 'p') || (str[n] == 'P')) ++state; else return false; break; case 5: if ((str[n] == 's') || (str[n] == 'S')) ++state; else if (str[n] == ':') state += 2; else return false; break; case 6: if (str[n] == ':') ++state; else return false; break; case 7: if (str[n] == '/') ++state; else return false; break; case 8: if (str[n] == '/') state = 0; else return false; break; case 100: if ((str[n] == 'a') || (str[n] == 'A')) ++state; else return false; break; case 101: if ((str[n] == 'i') || (str[n] == 'I')) ++state; else return false; break; case 102: if ((str[n] == 'l') || (str[n] == 'L')) ++state; else return false; break; case 103: if ((str[n] == 't') || (str[n] == 'T')) ++state; else return false; break; case 104: if ((str[n] == 'o') || (str[n] == 'O')) ++state; else return false; break; case 105: if (str[n] == ':') state = 0; else return false; break; } n += clen; } return (! state) ? true : false; }/*}}}*/ static bool_t modify_linelength (blockmail_t *blockmail, block_t *block, blockspec_t *bspec) /*{{{*/ { # define DOIT_NONE (0) # define DOIT_RESET (1 << 0) # define DOIT_NEWLINE (1 << 1) # define DOIT_IGNORE (1 << 2) # define DOIT_SKIP (1 << 3) int n; int len; const xmlChar *cont; int spos, slen; int space, dash; int spchr, dachr; int inspace, spacecount; int llen, wordstart; int doit; int skipcount; bool_t changed; xmlBufferEmpty (block -> out); len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); spos = 0; space = -1; dash = -1; spchr = -1; dachr = -1; inspace = 0; spacecount = 0; llen = 0; wordstart = 0; doit = DOIT_NONE; skipcount = 0; changed = false; for (n = 0; n < len; ) { if ((cont[n] == '\r') || (cont[n] == '\n')) { doit = DOIT_RESET; if (inspace && (spchr + inspace == llen)) { n = space; doit |= DOIT_NEWLINE | DOIT_IGNORE | DOIT_SKIP; skipcount = inspace + 1; } } else { if ((cont[n] == ' ') || (cont[n] == '\t')) { if (! inspace++) { space = n; spchr = llen; } spacecount = inspace; } else { if (inspace) { inspace = 0; wordstart = n; } if ((cont[n] == '-') && (llen > 2) && ((spchr == -1) || (llen - spchr > 2)) && (! islink (cont + wordstart, n - wordstart))) { dash = n; dachr = llen; } } if (++llen >= bspec -> linelength) if ((space != -1) || (dash != -1)) { if (space > dash) { if (! inspace) { n = space; doit = DOIT_RESET | DOIT_NEWLINE | DOIT_IGNORE | DOIT_SKIP; skipcount = spacecount; } } else { n = dash; doit = DOIT_RESET | DOIT_NEWLINE; } } } if (! (doit & DOIT_IGNORE)) n += xmlCharLength (cont[n]); if (doit) { slen = n - spos; if (slen > 0) xmlBufferAdd (block -> out, cont + spos, slen); if (doit & DOIT_NEWLINE) { xmlBufferAdd (block -> out, bspec -> linesep, bspec -> seplength); changed = true; } if (doit & DOIT_SKIP) { while ((skipcount-- > 0) && (n < len)) n += xmlCharLength (cont[n]); changed = true; } spos = n; space = -1; dash = -1; spchr = -1; dachr = -1; inspace = 0; spacecount = 0; llen = 0; wordstart = n; doit = DOIT_NONE; } } if (changed) { if (spos < len) xmlBufferAdd (block -> out, cont + spos, len - spos); SWAP (block); } return true; # undef DOIT_NONE # undef DOIT_RESET # undef DOIT_NEWLINE # undef DOIT_IGNORE # undef DOIT_SKIP }/*}}}*/
static bool_t modify_urls (blockmail_t *blockmail, receiver_t *rec, block_t *block) /*{{{*/ { int n; int len; const xmlChar *cont; int lstore; int state; char initial; char ch; int start, end; int mask; int clen; bool_t changed; xmlBufferEmpty (block -> out); len = xmlBufferLength (block -> in); cont = xmlBufferContent (block -> in); lstore = 0; state = ST_INITIAL; if (block -> nr == 1) initial = 'h'; else if (block -> nr == 2) initial = '<'; else initial = '\0'; start = -1; end = -1; mask = 1 << (block -> nr - 1); changed = false; for (n = 0; n <= len; ) { if (n < len) { clen = xmlCharLength (cont[n]); if ((clen == 1) && isascii ((char) cont[n])) { ch = (char) cont[n]; switch (state) { case ST_INITIAL: if (tolower (ch) == initial) { if (block -> nr == 1) { state = 1; start = n; } else if (block -> nr == 2) state = 100; } break; # define CHK(ccc) do { if ((ccc) == ch) ++state; else state = ST_INITIAL; } while (0) # define CCHK(ccc) do { if ((ccc) == tolower (ch)) ++state; else state = ST_INITIAL; } while (0) case 1: CCHK ('t'); break; case 2: CCHK ('t'); break; case 3: CCHK ('p'); break; case 4: ++state; if (tolower (ch) == 's') break; /* Fall through . . . */ case 5: CHK (':'); break; case 6: CHK ('/'); break; case 7: if (ch == '/') state = ST_START_FOUND; else state = ST_INITIAL; break; case 100: CCHK ('a'); break; # define HCHK(ccc) do { if ((ccc) == tolower (ch)) ++state; else if ('>' == ch) state = ST_INITIAL; else state = 101; } while (0) case 101: HCHK ('h'); break; case 102: HCHK ('r'); break; case 103: HCHK ('e'); break; case 104: HCHK ('f'); break; # undef HCHK case 105: CHK ('='); break; case 106: ++state; if (ch == '"') break; /* Fall through . . */ case 107: if (tolower (ch) == 'h') { state = 1; start = n; } else state = ST_INITIAL; break; case ST_START_FOUND: if (isspace ((int) ((unsigned char) ch)) || (ch == '"') || (ch == '>')) { end = n; state = ST_END_FOUND; } break; } # undef CHK # undef CCHK } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } else state = ST_INITIAL; } n += clen; } else { if (state == ST_START_FOUND) { end = n; state = ST_END_FOUND; } ++n; } if (state == ST_END_FOUND) { int ulen, m, o; ulen = end - start; for (m = 0; m < blockmail -> url_count; ++m) if ((blockmail -> url[m] -> usage & mask) && (blockmail -> url[m] -> dlen == ulen) && (! xmlStrncmp (blockmail -> url[m] -> dptr, cont + start, ulen))) break; if (m < blockmail -> url_count) { if (lstore < start) xmlBufferAdd (block -> out, cont + lstore, start - lstore); for (o = 0; o < rec -> url_count; ++o) if (rec -> url[o] -> uid == blockmail -> url[m] -> uid) break; if (o < rec -> url_count) xmlBufferAdd (block -> out, rec -> url[o] -> dptr, rec -> url[o] -> dlen); lstore = end; changed = true; } state = ST_INITIAL; } } if (changed) { if (lstore < len) xmlBufferAdd (block -> out, cont + lstore, len - lstore); SWAP (block); } return true; }/*}}}*/