/* 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; }/*}}}*/
I bool_t xmlEqual (xmlBufferPtr p1, xmlBufferPtr p2) /*{{{*/ { int len; const xmlChar *c1, *c2; len = xmlBufferLength (p1); if ((len == xmlBufferLength (p2)) && (c1 = xmlBufferContent (p1)) && (c2 = xmlBufferContent (p2)) && ((! len) || (! memcmp (c1, c2, len * sizeof (xmlChar))))) return true; return false; }/*}}}*/
/* 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 gchar * update_apply_xslt (updateJobPtr job) { xsltStylesheetPtr xslt = NULL; xmlOutputBufferPtr buf; xmlDocPtr srcDoc = NULL, resDoc = NULL; gchar *output = NULL; g_assert (NULL != job->result); do { srcDoc = xml_parse (job->result->data, job->result->size, NULL); if (!srcDoc) { g_warning("fatal: parsing request result XML source failed (%s)!", job->request->filtercmd); break; } /* load localization stylesheet */ xslt = xsltParseStylesheetFile (job->request->filtercmd); if (!xslt) { g_warning ("fatal: could not load filter stylesheet \"%s\"!", job->request->filtercmd); break; } resDoc = xsltApplyStylesheet (xslt, srcDoc, NULL); if (!resDoc) { g_warning ("fatal: applying stylesheet \"%s\" failed!", job->request->filtercmd); break; } buf = xmlAllocOutputBuffer (NULL); if (-1 == xsltSaveResultTo (buf, resDoc, xslt)) { g_warning ("fatal: retrieving result of filter stylesheet failed (%s)!", job->request->filtercmd); break; } #ifdef LIBXML2_NEW_BUFFER if (xmlOutputBufferGetSize (buf) > 0) output = xmlCharStrdup (xmlOutputBufferGetContent (buf)); #else if (xmlBufferLength (buf->buffer) > 0) output = xmlCharStrdup (xmlBufferContent (buf->buffer)); #endif xmlOutputBufferClose (buf); } while (FALSE); if (srcDoc) xmlFreeDoc (srcDoc); if (resDoc) xmlFreeDoc (resDoc); if (xslt) xsltFreeStylesheet (xslt); return output; }
void XMLInOut::MarkSection(void) { int numbytes; xmlTextWriterFlush(writer); numbytes = xmlBufferLength(buf); sections.push_front(numbytes); // cout << "Current marked buffer @ index-end:" << numbytes << endl // << "'" << (const char*)buf->content << "'" << endl; }
/*Write - writes xml tree of element to buffer output: data - is set to point to buffer containing xml data tlength - is set to length of xml data */ void CXMLElement::Write(char **data,int *tlength,Bool isformatted) { if (!isinited()) return; if (element->doc){ xmlBufferPtr buf; buf = xmlBufferCreate(); xmlNodeDump(buf, element->doc, element, 0, isformatted); *data = (char *)xmlStrdup(xmlBufferContent(buf)); *tlength = xmlBufferLength(buf); xmlBufferFree(buf); } }
/********************************************************************************* * 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" # ifndef I # define I /* */ # endif /* I */ # ifndef __MISC_C # define __MISC_C 1 I bool_t xmlEqual (xmlBufferPtr p1, xmlBufferPtr p2) /*{{{*/ { int len; const xmlChar *c1, *c2; len = xmlBufferLength (p1); if ((len == xmlBufferLength (p2)) && (c1 = xmlBufferContent (p1)) && (c2 = xmlBufferContent (p2)) && ((! len) || (! memcmp (c1, c2, len * sizeof (xmlChar))))) return true; return false; }/*}}}*/ I int xmlCharLength (xmlChar ch) /*{{{*/ { extern int xmlLengthtab[256]; return xmlLengthtab[ch]; }/*}}}*/ I int xmlStrictCharLength (xmlChar ch) /*{{{*/ { extern int xmlStrictLengthtab[256]; return xmlStrictLengthtab[ch]; }/*}}}*/ I int xmlValidPosition (const xmlChar *str, int length) /*{{{*/ { # define VALID(ccc) (((ccc) & 0xc0) == 0x80) int len, n; if (((len = xmlStrictCharLength (*str)) > 0) && (length >= len)) for (n = len; n > 1; ) { --n; if (! VALID (*(str + n))) { len = -1; break; } } else len = -1; return len; # undef VALID }/*}}}*/ I bool_t xmlValid (const xmlChar *str, int length) /*{{{*/ { int n; while (length > 0) if ((n = xmlValidPosition (str, length)) > 0) { str += n; length -= n; } else break; return length == 0 ? true : false; }/*}}}*/ I char * xml2string (xmlBufferPtr p) /*{{{*/ { int len = xmlBufferLength (p); const xmlChar *ptr = xmlBufferContent (p); char *rc; if (rc = malloc (len + 1)) { if (len > 0) memcpy (rc, ptr, len); rc[len] = '\0'; } return rc; }/*}}}*/ I const char * xml2char (const xmlChar *s) /*{{{*/ { return (const char *) s; }/*}}}*/ I const xmlChar * char2xml (const char *s) /*{{{*/ { return (const xmlChar *) s; }/*}}}*/ I const char * byte2char (const byte_t *b) /*{{{*/ { return (const char *) b; }/*}}}*/ I int xmlstrcmp (const xmlChar *s1, const char *s2) /*{{{*/ { return strcmp (xml2char (s1), s2); }/*}}}*/ I int xmlstrncmp (const xmlChar *s1, const char *s2, size_t n) /*{{{*/ { return strncmp (xml2char (s1), s2, n); }/*}}}*/ I long xml2long (xmlBufferPtr p) /*{{{*/ { int len = xmlBufferLength (p); const xmlChar *ptr = xmlBufferContent (p); char scratch[128]; if (len >= sizeof (scratch)) len = sizeof (scratch) - 1; memcpy (scratch, ptr, len); scratch[len] = '\0'; return strtol (scratch, NULL, 0); }/*}}}*/
/*}}}*/ }; 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); } }/*}}}*/ bool_t tag_match (tag_t *t, const xmlChar *name, int nlen) /*{{{*/ { const xmlChar *ptr; int len; len = xmlBufferLength (t -> name); if (len == nlen) { ptr = xmlBufferContent (t -> name); if (! memcmp (name, ptr, len)) return true; } return false; }/*}}}*/
/********************************************************************************* * 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" # ifndef I # define I /* */ # endif /* I */ # ifndef __MISC_C # define __MISC_C 1 I bool_t xmlEqual (xmlBufferPtr p1, xmlBufferPtr p2) /*{{{*/ { int len; const xmlChar *c1, *c2; len = xmlBufferLength (p1); if ((len == xmlBufferLength (p2)) && (c1 = xmlBufferContent (p1)) && (c2 = xmlBufferContent (p2)) && ((! len) || (! memcmp (c1, c2, len * sizeof (xmlChar))))) return true; return false; }/*}}}*/ I int xmlCharLength (xmlChar ch) /*{{{*/ { extern int xmlLengthtab[256]; return xmlLengthtab[ch]; }/*}}}*/ I int xmlStrictCharLength (xmlChar ch) /*{{{*/ { extern int xmlStrictLengthtab[256]; return xmlStrictLengthtab[ch]; }/*}}}*/ I int xmlValidPosition (const xmlChar *str, int length) /*{{{*/ { # define VALID(ccc) (((ccc) & 0xc0) == 0x80) int len, n; if (((len = xmlStrictCharLength (*str)) > 0) && (length >= len)) for (n = len; n > 1; ) { --n; if (! VALID (*(str + n))) { len = -1; break; } } else len = -1; return len; # undef VALID }/*}}}*/ I bool_t xmlValid (const xmlChar *str, int length) /*{{{*/ { int n; while (length > 0) if ((n = xmlValidPosition (str, length)) > 0) { str += n; length -= n; } else break; return length == 0 ? true : false; }/*}}}*/ I char * xml2string (xmlBufferPtr p) /*{{{*/ { int len = xmlBufferLength (p); const xmlChar *ptr = xmlBufferContent (p); char *rc; if (rc = malloc (len + 1)) { if (len > 0) memcpy (rc, ptr, len); rc[len] = '\0'; } return rc; }/*}}}*/
/** * create preferences minimal buffer from NftPrefsNode - compared to * nft_prefs_node_to_buffer, this doesn't include any encapsulation or headers. * Just the bare information contained in the node. This should be used to * export single nodes, e.g. for copying them to a clipboard * * @param p NftPrefs context * @param n NftPrefsNode * @result string holding xml representation of object (use free() to deallocate) * @note s. @ref nft_prefs_node_to_file for description */ char *nft_prefs_node_to_buffer_minimal(NftPrefs *p, NftPrefsNode * n) { if(!n) NFT_LOG_NULL(NULL); /* result pointer (xml dump) */ char *dump = NULL; /* add prefs version to node */ if(!(_updater_node_add_version(p, n))) { NFT_LOG(L_ERROR, "failed to add version to node \"%s\"", nft_prefs_node_get_name(n)); return NULL; } /* create buffer */ xmlBufferPtr buf; if(!(buf = xmlBufferCreate())) { NFT_LOG(L_ERROR, "failed to xmlBufferCreate()"); return NULL; } /* dump node */ if(xmlNodeDump(buf, n->doc, n, 0, true) < 0) { NFT_LOG(L_ERROR, "xmlNodeDump() failed"); goto _pntb_exit; } /* allocate buffer */ size_t length = xmlBufferLength(buf); if(!(dump = malloc(length + 1))) { NFT_LOG_PERROR("malloc()"); goto _pntb_exit; } /* copy buffer */ strncpy(dump, (char *) xmlBufferContent(buf), length); dump[length] = '\0'; _pntb_exit: xmlBufferFree(buf); return dump; }
string BEXMLTextReader::raw_xml() { xmlBufferPtr node_content = xmlBufferCreate(); xmlOutputBufferPtr node = (xmlOutputBufferPtr) xmlMalloc ( sizeof(xmlOutputBuffer) ); memset ( node, 0, (size_t) sizeof(xmlOutputBuffer) ); node->buffer = node_content; xmlNodeDumpOutput ( node, xml_document, xmlTextReaderCurrentNode ( reader ), 0, true, "UTF-8" ); const xmlChar * xml_data = xmlBufferContent ( (xmlBufferPtr)node_content ); size_t xml_length = xmlBufferLength ( node_content ); string xml_result ( (char *)xml_data, xml_length ); xmlFree ( (xmlChar *)xml_data ); return xml_result; } // raw_xml
G_GNUC_INTERNAL char * gvir_config_xml_node_to_string(xmlNodePtr node) { xmlBufferPtr xmlbuf; char *xml; if (node == NULL) return NULL; xmlbuf = xmlBufferCreate(); if (xmlNodeDump(xmlbuf, node->doc, node, 0, 1) < 0) xml = NULL; else xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf)); xmlBufferFree(xmlbuf); return xml; }
xmlChar* PmmFastDecodeString( int charset, const xmlChar *string, const xmlChar *encoding) { xmlCharEncodingHandlerPtr coder = NULL; xmlChar *retval = NULL; xmlBufferPtr in = NULL, out = NULL; if ( charset == XML_CHAR_ENCODING_UTF8 ) { return xmlStrdup( string ); } else if ( charset == XML_CHAR_ENCODING_ERROR ) { coder = xmlFindCharEncodingHandler( (const char *) encoding ); } else if ( charset == XML_CHAR_ENCODING_NONE ) { xs_warn("PmmFastDecodeString: no encoding found\n"); } else { coder= xmlGetCharEncodingHandler( charset ); } if ( coder != NULL ) { /* warn( "do encoding %s", string ); */ in = xmlBufferCreate(); out = xmlBufferCreate(); xmlBufferCat( in, string ); if ( xmlCharEncOutFunc( coder, out, in ) >= 0 ) { retval = xmlCharStrndup((const char *)xmlBufferContent(out), xmlBufferLength(out)); } else { xs_warn("PmmFastEncodeString: decoding error\n"); } xmlBufferFree( in ); xmlBufferFree( out ); xmlCharEncCloseFunc( coder ); } return retval; }
/** * Write the xml document out to a memory location. * @param xml The xml document * @param len The size of the memory buffer * @return a pointer to the memory location, or @c NULL if an error occurs. * @ingroup EXML_Write_Group */ void *exml_mem_write(EXML *xml, size_t *len) { xmlTextWriterPtr writer; xmlBufferPtr buf; CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE); buf = xmlBufferCreate(); writer = xmlNewTextWriterMemory( buf, 0 ); if (_exml_write(xml, writer)) { ecore_hash_set( xml->buffers, (void *) xmlBufferContent( buf ), buf ); *len = xmlBufferLength( buf ); return (void *) xmlBufferContent( buf ); } else { *len = 0; xmlBufferFree( buf ); return NULL; } }
/** * exsltStrReplaceFunction: * @ctxt: an XPath parser context * @nargs: the number of arguments * * Takes a string, and two node sets and returns the string with all strings in * the first node set replaced by all strings in the second node set. */ static void exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { int i, i_empty, n, slen0, rlen0, *slen, *rlen; void *mem = NULL; const xmlChar *src, *start; xmlChar *string, *search_str = NULL, *replace_str = NULL; xmlChar **search, **replace; xmlNodeSetPtr search_set = NULL, replace_set = NULL; xmlBufferPtr buf; if (nargs != 3) { xmlXPathSetArityError(ctxt); return; } /* get replace argument */ if (!xmlXPathStackIsNodeSet(ctxt)) replace_str = xmlXPathPopString(ctxt); else replace_set = xmlXPathPopNodeSet(ctxt); if (xmlXPathCheckError(ctxt)) goto fail_replace; /* get search argument */ if (!xmlXPathStackIsNodeSet(ctxt)) { search_str = xmlXPathPopString(ctxt); n = 1; } else { search_set = xmlXPathPopNodeSet(ctxt); n = search_set != NULL ? search_set->nodeNr : 0; } if (xmlXPathCheckError(ctxt)) goto fail_search; /* get string argument */ string = xmlXPathPopString(ctxt); if (xmlXPathCheckError(ctxt)) goto fail_string; /* check for empty search node list */ if (n <= 0) { exsltStrReturnString(ctxt, string, xmlStrlen(string)); goto done_empty_search; } /* allocate memory for string pointer and length arrays */ if (n == 1) { search = &search_str; replace = &replace_str; slen = &slen0; rlen = &rlen0; } else { mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int))); if (mem == NULL) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_malloc; } search = (xmlChar **) mem; replace = search + n; slen = (int *) (replace + n); rlen = slen + n; } /* process arguments */ i_empty = -1; for (i=0; i<n; ++i) { if (search_set != NULL) { search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]); if (search[i] == NULL) { n = i; goto fail_process_args; } } slen[i] = xmlStrlen(search[i]); if (i_empty < 0 && slen[i] == 0) i_empty = i; if (replace_set != NULL) { if (i < replace_set->nodeNr) { replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]); if (replace[i] == NULL) { n = i + 1; goto fail_process_args; } } else replace[i] = NULL; } else { if (i == 0) replace[i] = replace_str; else replace[i] = NULL; } if (replace[i] == NULL) rlen[i] = 0; else rlen[i] = xmlStrlen(replace[i]); } if (i_empty >= 0 && rlen[i_empty] == 0) i_empty = -1; /* replace operation */ buf = xmlBufferCreate(); if (buf == NULL) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer; } src = string; start = string; while (*src != 0) { int max_len = 0, i_match = 0; for (i=0; i<n; ++i) { if (*src == search[i][0] && slen[i] > max_len && xmlStrncmp(src, search[i], slen[i]) == 0) { i_match = i; max_len = slen[i]; } } if (max_len == 0) { if (i_empty >= 0 && start < src) { if (xmlBufferAdd(buf, start, src - start) || xmlBufferAdd(buf, replace[i_empty], rlen[i_empty])) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } start = src; } src += xmlUTF8Size(src); } else { if ((start < src && xmlBufferAdd(buf, start, src - start)) || (rlen[i_match] && xmlBufferAdd(buf, replace[i_match], rlen[i_match]))) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } src += slen[i_match]; start = src; } } if (start < src && xmlBufferAdd(buf, start, src - start)) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } /* create result node set */ exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf)); /* clean up */ fail_buffer_add: xmlBufferFree(buf); fail_buffer: fail_process_args: if (search_set != NULL) { for (i=0; i<n; ++i) xmlFree(search[i]); } if (replace_set != NULL) { for (i=0; i<n; ++i) { if (replace[i] != NULL) xmlFree(replace[i]); } } if (mem != NULL) xmlFree(mem); fail_malloc: done_empty_search: xmlFree(string); fail_string: if (search_set != NULL) xmlXPathFreeNodeSet(search_set); else xmlFree(search_str); fail_search: if (replace_set != NULL) xmlXPathFreeNodeSet(replace_set); else xmlFree(replace_str); fail_replace: return; }
/** * create preferences file from NftPrefsNode and child nodes * * This will create the same output as nft_prefs_node_to_file() would but * without all encapsulation/headers/footers/... of the underlying prefs mechanism. * e.g. for XML this omits the "<?xml version="1.0" encoding="UTF-8"?>" header. * This is used when one only needs an "incomplete" snippet of a configuration. * e.g. for copy/paste or to use the XInclude feature of XML * * @param p NftPrefs context * @param n NftPrefsNode * @param filename full path of file to be written * @param overwrite if a file called "filename" already exists, it * will be overwritten if this is "true", otherwise NFT_FAILURE will be returned * @result NFT_SUCCESS or NFT_FAILURE */ NftResult nft_prefs_node_to_file_minimal(NftPrefs *p, NftPrefsNode * n, const char *filename, bool overwrite) { if(!n || !filename) NFT_LOG_NULL(NFT_FAILURE); /* file already existing? */ struct stat sts; if(stat(filename, &sts) == -1) { /* continue if stat error was caused because file doesn't exist */ if(errno != ENOENT) { NFT_LOG(L_ERROR, "Failed to access \"%s\" - %s", filename, strerror(errno)); return NFT_FAILURE; } } /* stat succeeded, file exists */ else if(strcmp("-", filename) != 0) { /* remove old file? */ if(!overwrite) return NFT_FAILURE; /* delete existing file */ if(unlink(filename) == -1) { NFT_LOG(L_ERROR, "Failed to remove old version of \"%s\" - %s", filename, strerror(errno)); return NFT_FAILURE; } } /* overall result */ NftResult r = NFT_FAILURE; /* add prefs version to node */ if(!(_updater_node_add_version(p, n))) { NFT_LOG(L_ERROR, "failed to add version to node \"%s\"", nft_prefs_node_get_name(n)); return r; } /* create buffer */ xmlBufferPtr buf; if(!(buf = xmlBufferCreate())) { NFT_LOG(L_ERROR, "failed to xmlBufferCreate()"); return r; } /* dump node */ if(xmlNodeDump(buf, n->doc, n, 0, true) < 0) { NFT_LOG(L_ERROR, "xmlNodeDump() failed"); goto _pntf_exit; } /* stdout? */ int fd; if(strcmp("-", filename) == 0) { fd = STDOUT_FILENO; } /* open file */ else { #ifdef WIN32 if((fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1) #else if((fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP)) == -1) #endif { NFT_LOG_PERROR("open"); goto _pntf_exit; } } /* write to file */ ssize_t length = xmlBufferLength(buf); if(write(fd, (char *) xmlBufferContent(buf), length) != length) { NFT_LOG_PERROR("write"); goto _pntf_exit; } if(fd != STDOUT_FILENO) close(fd); r = NFT_SUCCESS; _pntf_exit: xmlBufferFree(buf); return r; }
gchar* xhtml_extract (xmlNodePtr xml, gint xhtmlMode, const gchar *defaultBase) { xmlBufferPtr buf; xmlChar *xml_base = NULL; gchar *result = NULL; xmlNs *ns; /* Create the new document and add the div tag*/ xmlDocPtr newDoc = xmlNewDoc (BAD_CAST "1.0" ); xmlNodePtr divNode = xmlNewNode (NULL, BAD_CAST "div"); xmlDocSetRootElement (newDoc, divNode); xmlNewNs (divNode, BAD_CAST "http://www.w3.org/1999/xhtml", NULL); /* Set the xml:base of the div tag */ xml_base = xmlNodeGetBase (xml->doc, xml); if (xml_base) { xmlNodeSetBase (divNode, xml_base ); xmlFree (xml_base); } else if (defaultBase) xmlNodeSetBase (divNode, BAD_CAST defaultBase); if (xhtmlMode == 0) { /* Read escaped HTML and convert to XHTML, placing in a div tag */ xmlDocPtr oldDoc; xmlNodePtr copiedNodes = NULL; xmlChar *escapedhtml; /* Parse the HTML into oldDoc*/ escapedhtml = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); if (escapedhtml) { escapedhtml = BAD_CAST g_strstrip ((gchar*) escapedhtml); /* stripping whitespaces to make empty string detection easier */ if (*escapedhtml) { /* never process empty content, xmlDocCopy() doesn't like it... */ xmlNodePtr body; oldDoc = xhtml_parse ((gchar*) escapedhtml, strlen ((gchar*) escapedhtml)); body = xhtml_find_body (oldDoc); /* Copy namespace from original documents root node. This is ro determine additional namespaces for item content. For example to handle RSS 2.0 feeds as provided by LiveJournal: <rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'> <channel> ... <item> ... <description>... <span class='ljuser' lj:user='someone' style='white-space: nowrap;'><a href='http://community.livejournal.com/someone/profile'><img src='http://stat.livejournal.com/img/community.gif' alt='[info]' width='16' height='16' style='vertical-align: bottom; border: 0; padding-right: 2px;' /></a><a href='http://community.livejournal.com/someone/'><b>someone</b></a></span> ...</description> ... </item> ... </channel> Then we will want to extract <description> and need to honour the xmlns:lj definition... */ ns = (xmlDocGetRootElement (xml->doc))->nsDef; while (ns) { xmlNewNs (divNode, ns->href, ns->prefix); ns = ns->next; } if (body) { /* Copy in the html tags */ copiedNodes = xmlDocCopyNodeList (newDoc, body->xmlChildrenNode); // FIXME: is the above correct? Why only operate on the first child node? // It might be unproblematic because all content is wrapped in a <div>... xmlAddChildList (divNode, copiedNodes); } xmlFreeDoc (oldDoc); xmlFree (escapedhtml); } } } else if (xhtmlMode == 1 || xhtmlMode == 2) { /* Read multiple XHTML tags and embed in div tag */ xmlNodePtr copiedNodes = xmlDocCopyNodeList (newDoc, xml->xmlChildrenNode); xmlAddChildList (divNode, copiedNodes); } buf = xmlBufferCreate (); xmlNodeDump (buf, newDoc, xmlDocGetRootElement (newDoc), 0, 0 ); if (xmlBufferLength (buf) > 0) result = (gchar*) xmlCharStrdup ((gchar*) xmlBufferContent (buf)); xmlBufferFree (buf); xmlFreeDoc (newDoc); return result; }
/*}}}*/ }; 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); } }/*}}}*/ bool_t tag_match (tag_t *t, const xmlChar *name, int nlen) /*{{{*/ { const xmlChar *ptr; int len; len = xmlBufferLength (t -> name); if (len == nlen) { ptr = xmlBufferContent (t -> name); if (! memcmp (name, ptr, len)) return true; } return false; }/*}}}*/ const xmlChar * tag_content (tag_t *t, blockmail_t *blockmail, receiver_t *rec, int *length) /*{{{*/ { *length = xmlBufferLength (t -> value); return xmlBufferContent (t -> value); }/*}}}*/
/** * verify_request: * @mng: the keys manager * * Verifies XML signature in the request (stdin). * * Returns 0 on success or a negative value if an error occurs. */ int verify_request(xmlSecKeysMngrPtr mngr) { xmlBufferPtr buffer = NULL; char buf[256]; xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int ret; int res = -1; assert(mngr); /* load request in the buffer */ buffer = xmlBufferCreate(); if(buffer == NULL) { fprintf(stdout,"Error: failed to create buffer\n"); goto done; } while(!feof(stdin)) { ret = fread(buf, 1, sizeof(buf), stdin); if(ret < 0) { fprintf(stdout,"Error: read failed\n"); goto done; } xmlBufferAdd(buffer, buf, ret); } /* is the document subbmitted from the form? */ if(strncmp((char*)xmlBufferContent(buffer), "_xmldoc=", 8) == 0) { xmlBufferShrink(buffer, 8); buffer->use = url_decode((char*)xmlBufferContent(buffer), xmlBufferLength(buffer)); } /** * Load doc */ doc = xmlReadMemory(xmlBufferContent(buffer), xmlBufferLength(buffer), NULL, NULL, XML_PARSE_NOENT | XML_PARSE_NOCDATA | XML_PARSE_PEDANTIC | XML_PARSE_NOCDATA); if (doc == NULL) { fprintf(stdout, "Error: unable to parse xml document (syntax error)\n"); goto done; } /* * Check the document is of the right kind */ if(xmlDocGetRootElement(doc) == NULL) { fprintf(stdout,"Error: empty document\n"); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stdout, "Error: start <dsig:Signature/> node not found\n"); goto done; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { fprintf(stdout,"Error: failed to create signature context\n"); goto done; } /* we would like to store and print out everything */ /* actually we would not because it opens a security hole dsigCtx->flags = XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES | XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES | XMLSEC_DSIG_FLAGS_STORE_SIGNATURE; */ /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { fprintf(stdout,"Error: signature verification failed\n"); goto done; } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { fprintf(stdout, "RESULT: Signature is OK\n"); } else { fprintf(stdout, "RESULT: Signature is INVALID\n"); } fprintf(stdout, "---------------------------------------------------\n"); xmlSecDSigCtxDebugDump(dsigCtx, stdout); /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } if(buffer != NULL) { xmlBufferFree(buffer); } return(res); }
/*}}}*/ }; 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; }/*}}}*/
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; }/*}}}*/
/* 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 }/*}}}*/
int main(int argc, char * argv[]) { int optc; int mode = 'g'; char *url; char *token = NULL; char *timeout = NULL; char *infile = NULL; char *owner = NULL; char *orig_url = NULL; char *content_type = "application/x-www-form-urlencoded"; char *auth_realm = NULL; char *pauth_realm = NULL; char *ns = NULL; int scope = ND_LOCK_SCOPE_EXCLUSIVE; int infinite = 0; int force_overwrite = 0; ndAuthCtxtPtr auth; /* OMIT xml errors. */ xmlSetGenericErrorFunc(NULL, null_error_handler); while ( (optc = getopt_long(argc, argv, optstring, long_options, NULL)) != -1 ) { switch (optc) { case 'c': mode = 'c'; orig_url = optarg; break; case 'm': mode = 'm'; orig_url = optarg; break; case 'e': mode = 'e'; { char *value = optarg; ndPropPtr prp = ndPropNew(); /* Locate the equal sign. */ while (*value && (*value != '=')) value++; /* Capture assigned value, * and crop property name. */ if (*value) *value++ = '\0'; prp->name = strdup(optarg); prp->ns = ns ? strdup(ns) : NULL; prp->value = *value ? strdup(value) : NULL; prp->type = *value ? NDPROP_PATCH : NDPROP_REMOVE; prp->next = propreq; propreq = prp; } break; case 'F': mode = 'F'; break; case 'g': mode = 'F'; { ndPropPtr prp = ndPropNew(); prp->name = strdup(optarg); prp->ns = ns ? strdup(ns) : NULL; prp->value = NULL; prp->type = NDPROP_FIND; prp->next = propreq; propreq = prp; } break; case 'l': mode = 'l'; timeout = "Infinite"; scope = ND_LOCK_SCOPE_EXCLUSIVE; break; case 'i': timeout = optarg; break; case 'n': mode = 'n'; format |= ND_PRINT_NAMEONLY; break; case 'o': owner = optarg; break; case 'd': mode = 'd'; break; case 'D': debug = 1; break; case 'f': force_overwrite = 1; break; case 'S': format |= ND_PRINT_AS_SEXP; break; case 'q': format |= ND_PRINT_QUIETLY; break; case 'v': format |= ND_PRINT_VERBOSELY; break; case 'a': auth_realm = optarg; break; case 'A': pauth_realm = optarg; break; case 'P': mode = 'P'; infile = optarg; break; case 'T': content_type = optarg; break; case 'N': ns = optarg; break; case 'u': mode = 'u'; break; case 'k': mode = 'k'; break; case 'r': infinite = 1; break; case 's': if (! strcmp("shared", optarg)) scope = ND_LOCK_SCOPE_SHARED; break; case 't': token = optarg; break; case 'p': mode = 'p'; infile = optarg; break; case 'V': print_version(argv[0]); exit(EXIT_SUCCESS); break; case 'h': /* Long help. */ usage(argv[0]); exit(EXIT_SUCCESS); break; case '?': /* Short help and catch-all. */ default: short_usage(argv[0]); exit(EXIT_FAILURE); break; } } url = argv[optind]; if (url == NULL) { fprintf(stderr, "%s: No target URL was specified.\n", basename(argv[0])); exit(EXIT_FAILURE); } auth = ndCreateAuthCtxt(authenticate, auth_notify, auth_realm, pauth_realm); switch (mode) { case 'c': { int code; code = ndCopy(orig_url, auth, url, force_overwrite, token); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "COPY failed, `%s'", ndReasonPhrase(code)); }; break; case 'e': { int code; ndNodeInfoPtr ret = NULL; if (propreq && propreq->next == NULL && propreq->ns == NULL) propreq->ns = ns; code = ndPropPatch(url, auth, propreq, token, &ret); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "PROPPATCH failed, `%s'", ndReasonPhrase(code)); else if (code == 207) ndNodeInfoListPrint(stdout, ret, format); }; break; case 'm': { int code; code = ndMove(orig_url, auth, url, force_overwrite, token); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "MOVE failed, `%s'", ndReasonPhrase(code)); }; break; case 'g': { #ifndef WAIT_FOR_END char *ct_return = NULL; int code; if (token != NULL) error_exit(format, "token is not required"); code = ndGetPrint(url, auth, &ct_return, stdout); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "GET failed, `%s'", ndReasonPhrase(code)); #else /* WAIT_FOR_END */ xmlBufferPtr buf = NULL; int code; char *ct_return = NULL; if (token != NULL) error_exit(format, "token is not required"); code = ndGet(url, auth, &ct_return, &buf); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "GET failed, `%s'", ndReasonPhrase(code)); if ( buf ) fprintf(stdout, "%s", xmlBufferContent(buf)); #endif /* WAIT_FOR_END */ }; break; case 'n': case 'F': { ndNodeInfoPtr ret = NULL; int code; int depth; if (token != NULL) error_exit(format, "token is not required"); depth = ( url[strlen(url) - 1] == '/' ) ? ( infinite ? ND_DEPTH_INFINITE : ND_DEPTH_1 ) : ND_DEPTH_0; if (propreq && propreq->next == NULL && propreq->ns == NULL) propreq->ns = ns; code = ndPropFind(url, auth, propreq, depth, (mode == 'n') ? 1 : 0, &ret); ndFreeAuthCtxt(auth); if (ret) ndNodeInfoListPrint(stdout, ret, format); else error_exit(format, "PROPFIND failed, `%s'", ndReasonPhrase(code)); }; break; case 'l': { ndLockInfoPtr lock = NULL; int code; int depth; depth = ( url[strlen(url) - 1] == '/' ) ? ( infinite ? ND_DEPTH_INFINITE : ND_DEPTH_1 ) : ND_DEPTH_0; code = ndLock(url, auth, depth, owner ? owner : getenv("USER"), scope, timeout, &lock); ndFreeAuthCtxt(auth); if (lock) { ndLockInfoPrint(stdout, lock, format); } else error_exit(format, "LOCK failed, `%s'", ndReasonPhrase(code)); }; break; case 'u': { int ret; int depth; if (token == NULL) error_exit(format, "token is required"); depth = ( url[strlen(url) - 1] == '/' ) ? ( infinite ? ND_DEPTH_INFINITE : ND_DEPTH_1 ) : ND_DEPTH_0; ret = ndUnlock(url, auth, depth, token); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(ret) ) error_exit(format, "UNLOCK failed, `%s'", ndReasonPhrase(ret)); }; break; case 'P': { xmlBufferPtr buf = xmlBufferCreate(); int len; unsigned char s [1024]; int ret; FILE *fp; if ((fp = fopen(infile, "r")) == NULL) error_exit(format, "%s, %s", infile, strerror(errno)); while ( (len = fread(s, sizeof(unsigned char), sizeof(s), fp)) > 0) xmlBufferAdd(buf, s, len); fclose(fp); ret = ndPostPrint(url, auth, (char *) xmlBufferContent(buf), xmlBufferLength(buf), &content_type, stdout); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(ret) ) error_exit(format, "POST failed, `%s'", ndReasonPhrase(ret)); }; break; case 'k': { int ret; ret = ndMkCol(url, auth, token); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(ret) ) error_exit(format, "MKCOL failed, `%s'", ndReasonPhrase(ret)); }; break; case 'd': { int ret; ret = ndDelete(url, auth, token); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(ret) ) error_exit(format, "DELETE failed, `%s'", ndReasonPhrase(ret)); }; break; case 'p': { int len; unsigned char s [1024]; int code; FILE *fp; ndNodeInfoPtr ret = NULL; xmlBufferPtr buf = xmlBufferCreate(); if ((fp = fopen(infile, "r")) == NULL) error_exit(format, "%s, %s", infile, strerror(errno)); while ( (len = fread(s, sizeof(unsigned char), sizeof(s), fp)) > 0) xmlBufferAdd(buf, s, len); fclose(fp); code = ndPut(url, auth, (char *) xmlBufferContent(buf), xmlBufferLength(buf), token, &ret); ndFreeAuthCtxt(auth); if ( RETURNED_AN_ERROR(code) ) error_exit(format, "PUT failed, `%s'", ndReasonPhrase(code)); else ndNodeInfoListPrint(stdout, ret, format); }; break; }; return 0; }; /* main(int, char * []) */
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; }/*}}}*/
static void do_save_calendar_rdf (FormatHandler *handler, ESourceSelector *selector, ECalClientSourceType type, gchar *dest_uri) { /* * According to some documentation about CSV, newlines 'are' allowed * in CSV-files. But you 'do' have to put the value between quotes. * The helper 'string_needsquotes' will check for that * * http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm * http://www.creativyst.com/cgi-bin/Prod/15/eg/csv2xml.pl */ ESource *primary_source; EClient *source_client; GError *error = NULL; GSList *objects = NULL; gchar *temp = NULL; GOutputStream *stream; if (!dest_uri) return; /* open source client */ primary_source = e_source_selector_ref_primary_selection (selector); source_client = e_cal_client_connect_sync ( primary_source, type, NULL, &error); g_object_unref (primary_source); /* Sanity check. */ g_return_if_fail ( ((source_client != NULL) && (error == NULL)) || ((source_client == NULL) && (error != NULL))); if (source_client == NULL) { display_error_message ( gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message); g_error_free (error); return; } stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (selector))), dest_uri, &error); if (stream && e_cal_client_get_object_list_as_comps_sync (E_CAL_CLIENT (source_client), "#t", &objects, NULL, NULL)) { GSList *iter; xmlBufferPtr buffer = xmlBufferCreate (); xmlDocPtr doc = xmlNewDoc ((xmlChar *) "1.0"); xmlNodePtr fnode; doc->children = xmlNewDocNode (doc, NULL, (const guchar *)"rdf:RDF", NULL); xmlSetProp (doc->children, (const guchar *)"xmlns:rdf", (const guchar *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#"); xmlSetProp (doc->children, (const guchar *)"xmlns", (const guchar *)"http://www.w3.org/2002/12/cal/ical#"); fnode = xmlNewChild (doc->children, NULL, (const guchar *)"Vcalendar", NULL); /* Should Evolution publicise these? */ xmlSetProp (fnode, (const guchar *)"xmlns:x-wr", (const guchar *)"http://www.w3.org/2002/12/cal/prod/Apple_Comp_628d9d8459c556fa#"); xmlSetProp (fnode, (const guchar *)"xmlns:x-lic", (const guchar *)"http://www.w3.org/2002/12/cal/prod/Apple_Comp_628d9d8459c556fa#"); /* Not sure if it's correct like this */ xmlNewChild (fnode, NULL, (const guchar *)"prodid", (const guchar *)"-//" PACKAGE_STRING "//iCal 1.0//EN"); /* Assuming GREGORIAN is the only supported calendar scale */ xmlNewChild (fnode, NULL, (const guchar *)"calscale", (const guchar *)"GREGORIAN"); temp = calendar_config_get_timezone (); xmlNewChild (fnode, NULL, (const guchar *)"x-wr:timezone", (guchar *) temp); g_free (temp); xmlNewChild (fnode, NULL, (const guchar *)"method", (const guchar *)"PUBLISH"); xmlNewChild (fnode, NULL, (const guchar *)"x-wr:relcalid", (guchar *) e_source_get_uid (primary_source)); xmlNewChild (fnode, NULL, (const guchar *)"x-wr:calname", (guchar *) e_source_get_display_name (primary_source)); /* Version of this RDF-format */ xmlNewChild (fnode, NULL, (const guchar *)"version", (const guchar *)"2.0"); for (iter = objects; iter; iter = iter->next) { ECalComponent *comp = iter->data; const gchar *temp_constchar; gchar *tmp_str = NULL; GSList *temp_list; ECalComponentDateTime temp_dt; struct icaltimetype *temp_time; gint *temp_int; ECalComponentText temp_comptext; xmlNodePtr c_node = xmlNewChild (fnode, NULL, (const guchar *)"component", NULL); xmlNodePtr node = xmlNewChild (c_node, NULL, (const guchar *)"Vevent", NULL); /* Getting the stuff */ e_cal_component_get_uid (comp, &temp_constchar); tmp_str = g_strdup_printf ("#%s", temp_constchar); xmlSetProp (node, (const guchar *)"about", (guchar *) tmp_str); g_free (tmp_str); add_string_to_rdf (node, "uid",temp_constchar); e_cal_component_get_summary (comp, &temp_comptext); add_string_to_rdf (node, "summary", temp_comptext.value); e_cal_component_get_description_list (comp, &temp_list); add_list_to_rdf (node, "description", temp_list, ECALCOMPONENTTEXT); if (temp_list) e_cal_component_free_text_list (temp_list); e_cal_component_get_categories_list (comp, &temp_list); add_list_to_rdf (node, "categories", temp_list, CONSTCHAR); if (temp_list) e_cal_component_free_categories_list (temp_list); e_cal_component_get_comment_list (comp, &temp_list); add_list_to_rdf (node, "comment", temp_list, ECALCOMPONENTTEXT); if (temp_list) e_cal_component_free_text_list (temp_list); e_cal_component_get_completed (comp, &temp_time); add_time_to_rdf (node, "completed", temp_time); if (temp_time) e_cal_component_free_icaltimetype (temp_time); e_cal_component_get_created (comp, &temp_time); add_time_to_rdf (node, "created", temp_time); if (temp_time) e_cal_component_free_icaltimetype (temp_time); e_cal_component_get_contact_list (comp, &temp_list); add_list_to_rdf (node, "contact", temp_list, ECALCOMPONENTTEXT); if (temp_list) e_cal_component_free_text_list (temp_list); e_cal_component_get_dtstart (comp, &temp_dt); add_time_to_rdf (node, "dtstart", temp_dt.value ? temp_dt.value : NULL); e_cal_component_free_datetime (&temp_dt); e_cal_component_get_dtend (comp, &temp_dt); add_time_to_rdf (node, "dtend", temp_dt.value ? temp_dt.value : NULL); e_cal_component_free_datetime (&temp_dt); e_cal_component_get_due (comp, &temp_dt); add_time_to_rdf (node, "due", temp_dt.value ? temp_dt.value : NULL); e_cal_component_free_datetime (&temp_dt); e_cal_component_get_percent (comp, &temp_int); add_nummeric_to_rdf (node, "percentComplete", temp_int); e_cal_component_get_priority (comp, &temp_int); add_nummeric_to_rdf (node, "priority", temp_int); e_cal_component_get_url (comp, &temp_constchar); add_string_to_rdf (node, "URL", temp_constchar); if (e_cal_component_has_attendees (comp)) { e_cal_component_get_attendee_list (comp, &temp_list); add_list_to_rdf (node, "attendee", temp_list, ECALCOMPONENTATTENDEE); if (temp_list) e_cal_component_free_attendee_list (temp_list); } e_cal_component_get_location (comp, &temp_constchar); add_string_to_rdf (node, "location", temp_constchar); e_cal_component_get_last_modified (comp, &temp_time); add_time_to_rdf (node, "lastModified",temp_time); /* Important note! * The documentation is not requiring this! * * if (temp_time) e_cal_component_free_icaltimetype (temp_time); * * Please uncomment and fix documentation if untrue * http://www.gnome.org/projects/evolution/developer-doc/libecal/ECalComponent.html * #e-cal-component-get-last-modified */ } /* I used a buffer rather than xmlDocDump: I want gio support */ xmlNodeDump (buffer, doc, doc->children, 2, 1); g_output_stream_write_all (stream, xmlBufferContent (buffer), xmlBufferLength (buffer), NULL, NULL, &error); g_output_stream_close (stream, NULL, NULL); e_cal_client_free_ecalcomp_slist (objects); xmlBufferFree (buffer); xmlFreeDoc (doc); } if (stream) g_object_unref (stream); g_object_unref (source_client); if (error != NULL) { display_error_message ( gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message); g_error_free (error); } }
static bool hidrd_xml_snk_flush(hidrd_snk *snk) { bool result = false; hidrd_xml_snk_inst *xml_snk = (hidrd_xml_snk_inst *)snk; bool valid; xmlBufferPtr xml_buf = NULL; xmlOutputBufferPtr xml_out_buf = NULL; void *new_buf; size_t new_size; XML_ERR_FUNC_BACKUP_DECL; free(xml_snk->err); xml_snk->err = strdup(""); XML_ERR_FUNC_SET(&xml_snk->err); /* Break any unfinished groups */ if (!xml_snk_group_break_branch(snk)) goto cleanup; /* Validate the document, if the schema is specified */ if (*xml_snk->schema != '\0' && (!xml_validate(&valid, xml_snk->doc, xml_snk->schema) || !valid)) goto cleanup; /* Create an XML buffer */ xml_buf = xmlBufferCreate(); if (xml_buf == NULL) goto cleanup; /* Create an XML output buffer from the generic buffer */ xml_out_buf = xmlOutputBufferCreateBuffer(xml_buf, NULL); if (xml_out_buf == NULL) goto cleanup; /* Format XML from the document */ if (xmlSaveFormatFileTo(xml_out_buf, xml_snk->doc, NULL, xml_snk->format) < 0) goto cleanup; /* xml_out_buf is closed by xmlSaveFormatFileTo */ xml_out_buf = NULL; /* Retrieve resulting size */ new_size = xmlBufferLength(xml_buf); /* If we have a location for the buffer pointer */ if (snk->pbuf != NULL) { /* Retention and update the buffer */ new_buf = realloc(*snk->pbuf, new_size); if (new_size > 0 && new_buf == NULL) XML_ERR_CLNP("failed to retention the output buffer"); memcpy(new_buf, xmlBufferContent(xml_buf), new_size); /* Update the buffer pointer */ *snk->pbuf = new_buf; } /* Output size */ if (snk->psize != NULL) *snk->psize = new_size; result = true; cleanup: if (xml_out_buf != NULL) xmlOutputBufferClose(xml_out_buf); if (xml_buf != NULL) xmlBufferFree(xml_buf); XML_ERR_FUNC_RESTORE; return result; }
/** * xmlXIncludeLoadTxt: * @ctxt: the XInclude context * @url: the associated URL * @nr: the xinclude node number * * Load the content, and store the result in the XInclude context */ static void xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlParserInputBufferPtr buf; xmlNodePtr node; xmlURIPtr uri; xmlChar *URL; int i; /* * Check the URL and remove any fragment identifier */ uri = xmlParseURI((const char *)url); if (uri == NULL) { xmlGenericError(xmlGenericErrorContext, "XInclude: invalid value URI %s\n", url); return; } if (uri->fragment != NULL) { xmlGenericError(xmlGenericErrorContext, "XInclude: fragment identifier forbidden for text: %s\n", uri->fragment); xmlFreeURI(uri); return; } URL = xmlSaveUri(uri); xmlFreeURI(uri); if (URL == NULL) { xmlGenericError(xmlGenericErrorContext, "XInclude: invalid value URI %s\n", url); return; } /* * Handling of references to the local document are done * directly through ctxt->doc. */ if (URL[0] == 0) { xmlGenericError(xmlGenericErrorContext, "XInclude: text serialization of document not available\n"); xmlFree(URL); return; } /* * Prevent reloading twice the document. */ for (i = 0; i < ctxt->txtNr; i++) { if (xmlStrEqual(URL, ctxt->txturlTab[i])) { node = xmlCopyNode(ctxt->txtTab[i], 1); goto loaded; } } /* * Load it. * Issue 62: how to detect the encoding */ buf = xmlParserInputBufferCreateFilename((const char *)URL, 0); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "XInclude: could not load %s\n", URL); xmlFree(URL); return; } node = xmlNewText(NULL); /* * Scan all chars from the resource and add the to the node */ while (xmlParserInputBufferRead(buf, 128) > 0) { int len; const xmlChar *content; content = xmlBufferContent(buf->buffer); len = xmlBufferLength(buf->buffer); for (i = 0; i < len; i++) { /* * TODO: if the encoding issue is solved, scan UTF8 chars instead */ if (!IS_CHAR(content[i])) { xmlGenericError(xmlGenericErrorContext, "XInclude: %s contains invalid char %d\n", URL, content[i]); } else { xmlNodeAddContentLen(node, &content[i], 1); } } xmlBufferShrink(buf->buffer, len); } xmlFreeParserInputBuffer(buf); xmlXIncludeAddTxt(ctxt, node, URL); loaded: /* * Add the element as the replacement copy. */ ctxt->repTab[nr] = node; xmlFree(URL); }