Exemple #1
0
					/* 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;
}/*}}}*/
Exemple #3
0
					/* 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;
}/*}}}*/
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
/*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;
}/*}}}*/
Exemple #10
0
/**
 * 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;
}
Exemple #13
0
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;
}
Exemple #14
0
/**
 * 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;
	}
}
Exemple #15
0
/**
 * 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;
}
Exemple #16
0
/**
 * 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;
}
Exemple #17
0
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>... &lt;span class=&apos;ljuser&apos; lj:user=&apos;someone&apos; style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://community.livejournal.com/someone/profile&apos;&gt;&lt;img src=&apos;http://stat.livejournal.com/img/community.gif&apos; alt=&apos;[info]&apos; width=&apos;16&apos; height=&apos;16&apos; style=&apos;vertical-align: bottom; border: 0; padding-right: 2px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://community.livejournal.com/someone/&apos;&gt;&lt;b&gt;someone&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; ...</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);
	}
}/*}}}*/
Exemple #21
0
/*********************************************************************************
 * 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;
}/*}}}*/
Exemple #22
0
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;
}/*}}}*/
Exemple #23
0
					/* 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
}/*}}}*/
Exemple #24
0
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 * []) */
Exemple #25
0
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;
}/*}}}*/
Exemple #26
0
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);
	}
}
Exemple #27
0
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);
}