예제 #1
0
static void CreateWildfireSampleMessage(StrBuf *OutBuf)
{
	JsonValue *Error;
		
	StrBuf *Buf;
	StrBuf *Header;
	StrBuf *Json;
	int n = 1;

	Header = NewStrBuf();
	Json = NewStrBuf();

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__,  HKEY("Warn message"), eWARN);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Error message"), eERROR);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);


	Buf = NewStrBufPlain(HKEY("test error message"));
	Error = WildFireException(HKEY(__FILE__), __LINE__, Buf, 1);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);

	FreeStrBuf(&Buf);
	FreeStrBuf(&Json);
	FreeStrBuf(&Header);

}
예제 #2
0
/*
 * Look for URL's embedded in a buffer and make them linkable.  We use a
 * target window in order to keep the Citadel session in its own window.
 */
void UrlizeText(StrBuf* Target, StrBuf *Source, StrBuf *WrkBuf)
{
	int len, UrlLen, Offset, TrailerLen;
	const char *start, *end, *pos;
	
	FlushStrBuf(Target);

	start = NULL;
	len = StrLength(Source);
	end = ChrPtr(Source) + len;
	for (pos = ChrPtr(Source); (pos < end) && (start == NULL); ++pos) {
		if (!strncasecmp(pos, "http://", 7))
			start = pos;
		else if (!strncasecmp(pos, "ftp://", 6))
			start = pos;
	}

	if (start == NULL) {
		StrBufAppendBuf(Target, Source, 0);
		return;
	}
	FlushStrBuf(WrkBuf);

	for (pos = ChrPtr(Source) + len; pos > start; --pos) {
		if (  (!isprint(*pos))
		   || (isspace(*pos))
		   || (*pos == '{')
		   || (*pos == '}')
		   || (*pos == '|')
		   || (*pos == '\\')
		   || (*pos == '^')
		   || (*pos == '[')
		   || (*pos == ']')
		   || (*pos == '`')
		   || (*pos == '<')
		   || (*pos == '>')
		   || (*pos == '(')
		   || (*pos == ')')
		) {
			end = pos;
		}
	}
	
	UrlLen = end - start;
	StrBufAppendBufPlain(WrkBuf, start, UrlLen, 0);

	Offset = start - ChrPtr(Source);
	if (Offset != 0)
		StrBufAppendBufPlain(Target, ChrPtr(Source), Offset, 0);
	StrBufAppendPrintf(Target, "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
			   LB, QU, ChrPtr(WrkBuf), QU, QU, TARGET, 
			   QU, RB, ChrPtr(WrkBuf), LB, RB);

	TrailerLen = StrLength(Source) - (end - ChrPtr(Source));
	if (TrailerLen > 0)
		StrBufAppendBufPlain(Target, end, TrailerLen, 0);
}
예제 #3
0
void 
HttpDetachModule_CONTEXT
(ParsedHttpHdrs *httpreq)
{
	FlushStrBuf(httpreq->PlainArgs);
	FlushStrBuf(httpreq->HostHeader);
	FlushStrBuf(httpreq->this_page);
	FlushStrBuf(httpreq->PlainArgs);
	DeleteHash(&httpreq->HTTPHeaders);
	memset(&httpreq->HR, 0, sizeof(HdrRefs));
}
예제 #4
0
파일: notes.c 프로젝트: mingodad/citadel
void render_MIME_VNote(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
{
	wc_mime_attachment *Mime = CTX(CTX_MIME_ATACH);

	if (StrLength(Mime->Data) == 0)
		MimeLoadData(Mime);
	if (StrLength(Mime->Data) > 0) {
		struct vnote *v;
		StrBuf *Buf;
		char *vcard;

		Buf = NewStrBuf();
		vcard = SmashStrBuf(&Mime->Data);
		v = vnote_new_from_str(vcard);
		free (vcard);
		if (v) {
			WCTemplputParams TP;
			
			memset(&TP, 0, sizeof(WCTemplputParams));
			TP.Filter.ContextType = CTX_VNOTE;
			TP.Context = v;
			DoTemplate(HKEY("mail_vnoteitem"),
				   Buf, &TP);
			
			vnote_free(v);
			Mime->Data = Buf;
		}
		else {
			if (Mime->Data == NULL)
				Mime->Data = NewStrBuf();
			else
				FlushStrBuf(Mime->Data);
		}
	}
}
예제 #5
0
void xrds_xml_end(void *data, const char *supplied_el) {
	struct xrds *xrds = (struct xrds *) data;

	--xrds->nesting_level;

	if (!strcasecmp(supplied_el, "XRD")) {
		--xrds->in_xrd;
	}

	else if (!strcasecmp(supplied_el, "type")) {
		if (	(xrds->in_xrd)
			&& (!strcasecmp(ChrPtr(xrds->CharData), "http://specs.openid.net/auth/2.0/server"))
		) {
			xrds->current_service_is_oid2auth = 1;
		}
		if (	(xrds->in_xrd)
			&& (!strcasecmp(ChrPtr(xrds->CharData), "http://specs.openid.net/auth/2.0/signon"))
		) {
			xrds->current_service_is_oid2auth = 1;
			/* FIXME in this case, the Claimed ID should be considered immutable */
		}
	}

	else if (!strcasecmp(supplied_el, "uri")) {
		if (xrds->in_xrd) {
			FlushStrBuf(xrds->current_service_uri);
			StrBufAppendBuf(xrds->current_service_uri, xrds->CharData, 0);
		}
	}

	else if (!strcasecmp(supplied_el, "service")) {
		if (	(xrds->in_xrd)
			&& (xrds->current_service_priority < xrds->selected_service_priority)
			&& (xrds->current_service_is_oid2auth)
		) {
			xrds->selected_service_priority = xrds->current_service_priority;
			FlushStrBuf(xrds->selected_service_uri);
			StrBufAppendBuf(xrds->selected_service_uri, xrds->current_service_uri, 0);
		}

	}

	FlushStrBuf(xrds->CharData);
}
예제 #6
0
파일: webcit.c 프로젝트: henri14/citadel
/*
 * Convenience functions to wrap around asynchronous ajax responses
 */
void begin_ajax_response(void) {
	wcsession *WCC = WC;

	FlushStrBuf(WCC->HBuf);
	output_headers(0, 0, 0, 0, 0, 0);

	hprintf("Content-type: text/html; charset=UTF-8\r\n"
		"Server: %s\r\n"
		"Connection: close\r\n"
		,
		PACKAGE_STRING);
	begin_burst();
}
예제 #7
0
void OverrideRequest(ParsedHttpHdrs *Hdr, const char *Line, long len)
{
	StrBuf *Buf = NewStrBuf();

	if (Hdr->HR.ReqLine != NULL) {
		FlushStrBuf(Hdr->HR.ReqLine);
		StrBufPlain(Hdr->HR.ReqLine, Line, len);
	}
	else {
		Hdr->HR.ReqLine = NewStrBufPlain(Line, len);
	}
	ReadHttpSubject(Hdr, Hdr->HR.ReqLine, Buf);

	FreeStrBuf(&Buf);
}
예제 #8
0
파일: webcit.c 프로젝트: henri14/citadel
void
SessionDetachModule_WEBCIT
(wcsession *sess)
{
	DeleteHash(&sess->Directory);

	FreeStrBuf(&sess->upload);
	sess->upload_length = 0;
	
	FreeStrBuf(&sess->trailing_javascript);

	if (StrLength(sess->WBuf) > SIZ * 30) /* Bigger than 120K? release. */
	{
		FreeStrBuf(&sess->WBuf);
		sess->WBuf = NewStrBuf();
	}
	else
		FlushStrBuf(sess->WBuf);
	FlushStrBuf(sess->HBuf);
	if (StrLength(sess->ImportantMsg) > 0) {
		FlushStrBuf(sess->ImportantMsg);
	}

}
예제 #9
0
파일: imap_acl.c 프로젝트: mingodad/citadel
/*
 * Given the bits returned by CtdlRoomAccess(), populate a string buffer
 * with IMAP ACL format flags.   This code is common to GETACL and MYRIGHTS.
 */
void imap_acl_flags(StrBuf *rights, int ra)
{
	FlushStrBuf(rights);

	/* l - lookup (mailbox is visible to LIST/LSUB commands)
	 * r - read (SELECT the mailbox, perform STATUS et al)
	 * s - keep seen/unseen information across sessions (STORE SEEN flag)
	 */
	if (	(ra & UA_KNOWN)					/* known rooms */
	   ||	((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED))	/* zapped rooms */
	) {
		StrBufAppendBufPlain(rights, HKEY("l"), 0);
		StrBufAppendBufPlain(rights, HKEY("r"), 0);
		StrBufAppendBufPlain(rights, HKEY("s"), 0);

		/* Only output the remaining flags if the room is known */

		/* w - write (set or clear flags other than SEEN or DELETED, not supported in Citadel */

		/* i - insert (perform APPEND, COPY into mailbox) */
		/* p - post (send mail to submission address for mailbox - not enforced) */
		/* c - create (CREATE new sub-mailboxes) */
		if (ra & UA_POSTALLOWED) {
			StrBufAppendBufPlain(rights, HKEY("i"), 0);
			StrBufAppendBufPlain(rights, HKEY("p"), 0);
			StrBufAppendBufPlain(rights, HKEY("c"), 0);
		}

		/* d - delete messages (STORE DELETED flag, perform EXPUNGE) */
		if (ra & UA_DELETEALLOWED) {
			StrBufAppendBufPlain(rights, HKEY("d"), 0);
		}

		/* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
		if (ra & UA_ADMINALLOWED) {
			/*
			 * This is the correct place to put the "a" flag.  We are leaving
			 * it commented out for now, because it implies that we could
			 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS.  Since these
			 * commands are not yet implemented, omitting the flag should
			 * theoretically prevent compliant clients from attempting to
			 * perform them.
			 *
			 * StrBufAppendBufPlain(rights, HKEY("a"), 0);
			 */
		}
	}
}
예제 #10
0
void xrds_xml_start(void *data, const char *supplied_el, const char **attr) {
	struct xrds *xrds = (struct xrds *) data;
	int i;

	++xrds->nesting_level;

	if (!strcasecmp(supplied_el, "XRD")) {
		++xrds->in_xrd;
	}

	else if (!strcasecmp(supplied_el, "service")) {
		xrds->current_service_priority = 0;
		xrds->current_service_is_oid2auth = 0;
		for (i=0; attr[i] != NULL; i+=2) {
			if (!strcasecmp(attr[i], "priority")) {
				xrds->current_service_priority = atoi(attr[i+1]);
			}
		}
	}

	FlushStrBuf(xrds->CharData);
}
예제 #11
0
static void TestHTML2ASCII_line(void)
{
	int fdin = 0;// STDIN
	const char *Err;
	StrBuf *Source;
	char *Target;

	Source = NewStrBuf();

	while (fdin == 0) {
		
		StrBufTCP_read_line(Source, &fdin, 0, &Err);
		printf("the source:>%s<\n", ChrPtr(Source));
		Target = html_to_ascii(ChrPtr(Source), StrLength(Source), 80, 0);
		
		printf("the target:>%s<\n", Target);
		FlushStrBuf(Source);
		free(Target);
	}

	FreeStrBuf(&Source);
}
예제 #12
0
/*
 * Parse an XRDS document.
 * If an OpenID Provider URL is discovered, op_url to that value and return nonzero.
 * If nothing useful happened, return 0.
 */
int parse_xrds_document(StrBuf *ReplyBuf) {
	ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;
	struct xrds xrds;
	int return_value = 0;

	memset(&xrds, 0, sizeof (struct xrds));
	xrds.selected_service_priority = INT_MAX;
	xrds.CharData = NewStrBuf();
	xrds.current_service_uri = NewStrBuf();
	xrds.selected_service_uri = NewStrBuf();
	XML_Parser xp = XML_ParserCreate(NULL);
	if (xp) {
		XML_SetUserData(xp, &xrds);
		XML_SetElementHandler(xp, xrds_xml_start, xrds_xml_end);
		XML_SetCharacterDataHandler(xp, xrds_xml_chardata);
		XML_Parse(xp, ChrPtr(ReplyBuf), StrLength(ReplyBuf), 0);
		XML_Parse(xp, "", 0, 1);
		XML_ParserFree(xp);
	}
	else {
		syslog(LOG_ALERT, "Cannot create XML parser");
	}

	if (xrds.selected_service_priority < INT_MAX) {
		if (oiddata->op_url == NULL) {
			oiddata->op_url = NewStrBuf();
		}
		FlushStrBuf(oiddata->op_url);
		StrBufAppendBuf(oiddata->op_url, xrds.selected_service_uri, 0);
		return_value = openid_disco_xrds;
	}

	FreeStrBuf(&xrds.CharData);
	FreeStrBuf(&xrds.current_service_uri);
	FreeStrBuf(&xrds.selected_service_uri);

	return(return_value);
}
예제 #13
0
/*
 * This is the back end for flush_conversations_to_disk()
 * At this point we've isolated a single conversation (struct imlog)
 * and are ready to write it to disk.
 */
void flush_individual_conversation(struct imlog *im) {
	struct CtdlMessage *msg;
	long msgnum = 0;
	char roomname[ROOMNAMELEN];
	StrBuf *MsgBuf, *FullMsgBuf;

	StrBufAppendBufPlain(im->conversation, HKEY(
		"</body>\r\n"
		"</html>\r\n"
		), 0
	);

	MsgBuf = StrBufRFC2047encodeMessage(im->conversation);
	FlushStrBuf(im->conversation);
	FullMsgBuf = NewStrBufPlain(NULL, StrLength(im->conversation) + 100);

	StrBufAppendBufPlain(FullMsgBuf, HKEY(
			"Content-type: text/html; charset=UTF-8\r\n"
			"Content-Transfer-Encoding: quoted-printable\r\n"
			"\r\n"
			), 0);
	StrBufAppendBuf (FullMsgBuf, MsgBuf, 0);
	FreeStrBuf(&MsgBuf);

	msg = malloc(sizeof(struct CtdlMessage));
	memset(msg, 0, sizeof(struct CtdlMessage));
	msg->cm_magic = CTDLMESSAGE_MAGIC;
	msg->cm_anon_type = MES_NORMAL;
	msg->cm_format_type = FMT_RFC822;
	if (!IsEmptyStr(im->usernames[0])) {
		CM_SetField(msg, eAuthor, im->usernames[0], strlen(im->usernames[0]));
	} else {
		CM_SetField(msg, eAuthor, HKEY("Citadel"));
	}
	if (!IsEmptyStr(im->usernames[1])) {
		CM_SetField(msg, eRecipient, im->usernames[1], strlen(im->usernames[1]));
	}

	CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM));
	CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
	CM_SetAsFieldSB(msg, eMesageText, &FullMsgBuf);	/* we own this memory now */

	/* Start with usernums[1] because it's guaranteed to be higher than usernums[0],
	 * so if there's only one party, usernums[0] will be zero but usernums[1] won't.
	 * Create the room if necessary.  Note that we create as a type 5 room rather
	 * than 4, which indicates that it's a personal room but we've already supplied
	 * the namespace prefix.
	 *
	 * In the unlikely event that usernums[1] is zero, a room with an invalid namespace
	 * prefix will be created.  That's ok because the auto-purger will clean it up later.
	 */
	snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[1], PAGELOGROOM);
	CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS);
	msgnum = CtdlSubmitMsg(msg, NULL, roomname, 0);
	CM_Free(msg);

	/* If there is a valid user number in usernums[0], save a copy for them too. */
	if (im->usernums[0] > 0) {
		snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[0], PAGELOGROOM);
		CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS);
		CtdlSaveMsgPointerInRoom(roomname, msgnum, 0, NULL);
	}

	/* Finally, if we're logging instant messages globally, do that now. */
	if (!IsEmptyStr(config.c_logpages)) {
		CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);
		CtdlSaveMsgPointerInRoom(config.c_logpages, msgnum, 0, NULL);
	}

}
예제 #14
0
파일: dav_put.c 프로젝트: mingodad/citadel
/*
 * The pathname is always going to take one of two formats:
 * [/groupdav/]room_name/euid	(GroupDAV)
 * [/groupdav/]room_name		(webcal)
 */
void dav_put(void) 
{
	wcsession *WCC = WC;
	StrBuf *dav_roomname;
	StrBuf *dav_uid;
	long new_msgnum = (-2L);
	long old_msgnum = (-1L);
	char buf[SIZ];
	int n = 0;

	if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("The object you requested was not found.\r\n");
		end_burst();
		return;
	}

	dav_roomname = NewStrBuf();;
	dav_uid = NewStrBuf();;
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
	StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
	if ((!strcasecmp(ChrPtr(dav_uid), "ics")) || 
	    (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
		FlushStrBuf(dav_uid);
	}

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("There is no folder called \"%s\" on this server.\r\n",
			ChrPtr(dav_roomname));
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);		
		return;
	}

	/*
	 * If an HTTP If-Match: header is present, the client is attempting
	 * to replace an existing item.  We have to check to see if the
	 * message number associated with the supplied uid matches what the
	 * client is expecting.  If not, the server probably contains a newer
	 * version, so we fail...
	 */
	if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
		syslog(LOG_DEBUG, "dav_ifmatch: %s\n", ChrPtr(WCC->Hdr->HR.dav_ifmatch));
		old_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
		syslog(LOG_DEBUG, "old_msgnum:  %ld\n", old_msgnum);
		if (StrTol(WCC->Hdr->HR.dav_ifmatch) != old_msgnum) {
			hprintf("HTTP/1.1 412 Precondition Failed\r\n");
			syslog(LOG_INFO, "HTTP/1.1 412 Precondition Failed (ifmatch=%ld, old_msgnum=%ld)\r\n",
				StrTol(WCC->Hdr->HR.dav_ifmatch), old_msgnum);
			dav_common_headers();
			
			end_burst();
			FreeStrBuf(&dav_roomname);
			FreeStrBuf(&dav_uid);
			return;
		}
	}

	/** PUT on the collection itself uploads an ICS of the entire collection.
	 */
	if (StrLength(dav_uid) == 0) {
		dav_put_bigics();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/*
	 * We are cleared for upload!  We use the new calling syntax for ENT0
	 * which allows a confirmation to be sent back to us.  That's how we
	 * extract the message ID.
	 */
	serv_puts("ENT0 1|||4|||1|");
	serv_getln(buf, sizeof buf);
	if (buf[0] != '8') {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("%s\r\n", &buf[4]);
		end_burst();
		return;
	}

	/* Send the content to the Citadel server */
	//serv_printf("Content-type: %s\n\n", WCC->upload_content_type);
	serv_putbuf(WCC->upload);
	serv_puts("\n000");

	/* Fetch the reply from the Citadel server */
	n = 0;
	FlushStrBuf(dav_uid);
	while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
		switch(n++) {
		case 0: 
			new_msgnum = atol(buf);
			break;
		case 1:	
			syslog(LOG_DEBUG, "new_msgnum=%ld (%s)\n", new_msgnum, buf);
			break;
		case 2: 
			StrBufAppendBufPlain(dav_uid, buf, -1, 0);
			break;
		default:
			break;
		}
	}

	/* Tell the client what happened. */

	/* Citadel failed in some way? */
	if (new_msgnum < 0L) {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("new_msgnum is %ld\r\n"
			"\r\n", new_msgnum);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We created this item for the first time. */
	if (old_msgnum < 0L) {
	        char escaped_uid[1024];
		hprintf("HTTP/1.1 201 Created\r\n");
		syslog(LOG_DEBUG, "HTTP/1.1 201 Created\r\n");
		dav_common_headers();
		hprintf("etag: \"%ld\"\r\n", new_msgnum);
		hprintf("Location: ");
		dav_identify_hosthdr();
		hprintf("/groupdav/");/* TODO */
		hurlescputs(ChrPtr(dav_roomname));
	        euid_escapize(escaped_uid, ChrPtr(dav_uid));
	        hprintf("/%s\r\n", escaped_uid);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We modified an existing item. */
	hprintf("HTTP/1.1 204 No Content\r\n");
	syslog(LOG_DEBUG, "HTTP/1.1 204 No Content\r\n");
	dav_common_headers();
	hprintf("Etag: \"%ld\"\r\n", new_msgnum);
	/* The item we replaced has probably already been deleted by
	 * the Citadel server, but we'll do this anyway, just in case.
	 */
	serv_printf("DELE %ld", old_msgnum);
	serv_getln(buf, sizeof buf);
	begin_burst();
	end_burst();
	FreeStrBuf(&dav_roomname);
	FreeStrBuf(&dav_uid);
	return;
}
예제 #15
0
/* 
 * Locate a <link> tag and, given its 'rel=' parameter, return its 'href' parameter
 */
void extract_link(StrBuf *target_buf, const char *rel, long repllen, StrBuf *source_buf)
{
	int i;
	const char *ptr;
	const char *href_start = NULL;
	const char *href_end = NULL;
	const char *link_tag_start = NULL;
	const char *link_tag_end = NULL;
	const char *rel_start = NULL;
	const char *rel_end = NULL;

	if (!target_buf) return;
	if (!rel) return;
	if (!source_buf) return;

	ptr = ChrPtr(source_buf);

	FlushStrBuf(target_buf);
	while (ptr = cbmstrcasestr(ptr, "<link"), ptr != NULL) {

		link_tag_start = ptr;
		link_tag_end = strchr(ptr, '>');
		if (link_tag_end == NULL)
			break;
		for (i=0; i < 1; i++ ){
			rel_start = cbmstrcasestr(link_tag_start, "rel=");
			if ((rel_start == NULL) ||
			    (rel_start > link_tag_end)) 
				continue;

			rel_start = strchr(rel_start, '\"');
			if ((rel_start == NULL) ||
			    (rel_start > link_tag_end)) 
				continue;
			++rel_start;
			rel_end = strchr(rel_start, '\"');
			if ((rel_end == NULL) ||
			    (rel_end == rel_start) ||
			    (rel_end >= link_tag_end) ) 
				continue;
			if (strncasecmp(rel, rel_start, repllen)!= 0)
				continue; /* didn't match? never mind... */
			
			href_start = cbmstrcasestr(link_tag_start, "href=");
			if ((href_start == NULL) || 
			    (href_start >= link_tag_end)) 
				continue;
			href_start = strchr(href_start, '\"');
			if ((href_start == NULL) |
			    (href_start >= link_tag_end)) 
				continue;
			++href_start;
			href_end = strchr(href_start, '\"');
			if ((href_end == NULL) || 
			    (href_end == href_start) ||
			    (href_start >= link_tag_end)) 
				continue;
			StrBufPlain(target_buf, href_start, href_end - href_start);
		}
		ptr = link_tag_end;	
	}
}
예제 #16
0
void render_MIME_ICS_TPL(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
{
	wc_mime_attachment *Mime = CTX(CTX_MIME_ATACH);
	icalproperty_method the_method = ICAL_METHOD_NONE;
	icalproperty *method = NULL;
	icalcomponent *cal = NULL;
	icalcomponent *c = NULL;
        WCTemplputParams SubTP;
        WCTemplputParams SuperTP;

	static int divcount = 0;

	if (StrLength(Mime->Data) == 0) {
		MimeLoadData(Mime);
	}
	if (StrLength(Mime->Data) > 0) {
		cal = icalcomponent_new_from_string(ChrPtr(Mime->Data));
	}
	if (cal == NULL) {
		StrBufAppendPrintf(Mime->Data, _("There was an error parsing this calendar item."));
		StrBufAppendPrintf(Mime->Data, "<br>\n");
		return;
	}

	putlbstr("divname",  ++divcount);


	putbstr("cal_partnum", NewStrBufDup(Mime->PartNum));
	putlbstr("msgnum", Mime->msgnum);

        memset(&SubTP, 0, sizeof(WCTemplputParams));
        memset(&SuperTP, 0, sizeof(WCTemplputParams));

	/*//ical_dezonify(cal); */

	/* If the component has subcomponents, recurse through them. */
	c = icalcomponent_get_first_component(cal, ICAL_ANY_COMPONENT);
        c = (c != NULL) ? c : cal;

	method = icalcomponent_get_first_property(cal, ICAL_METHOD_PROPERTY);
	if (method != NULL) {
		the_method = icalproperty_get_method(method);
	}

	StackContext (TP,
		      &SuperTP,
		      &the_method,
		      CTX_ICALMETHOD,
		      0,
		      TP->Tokens);

	StackContext (&SuperTP, 
		      &SubTP, 
		      c,
		      CTX_ICAL,
		      0,
		      SuperTP.Tokens);
	FlushStrBuf(Mime->Data);
///	DoTemplate(HKEY("ical_attachment_display"), Mime->Data, &SubTP);
	DoTemplate(HKEY("ical_edit"), Mime->Data, &SubTP);

	/*/ cal_process_object(Mime->Data, cal, 0, Mime->msgnum, ChrPtr(Mime->PartNum)); */

	/* Free the memory we obtained from libical's constructor */
	StrBufPlain(Mime->ContentType, HKEY("text/html"));
	StrBufAppendPrintf(WC->trailing_javascript,
		"eventEditAllDay();		\n"
		"RecurrenceShowHide();		\n"
		"EnableOrDisableCheckButton();	\n"
	);

	UnStackContext(&SuperTP);
	UnStackContext(&SubTP);
	icalcomponent_free(cal);
}
예제 #17
0
파일: webcit.c 프로젝트: henri14/citadel
/*
 * Entry point for WebCit transaction
 */
void session_loop(void)
{
	int xhttp;
	StrBuf *Buf;
	
	/*
	 * We stuff these with the values coming from the client cookies,
	 * so we can use them to reconnect a timed out session if we have to.
	 */
	wcsession *WCC;
      
	WCC= WC;
	WCC->upload_length = 0;
	WCC->upload = NULL;
	WCC->Hdr->nWildfireHeaders = 0;

	if (WCC->Hdr->HR.ContentLength > 0) {
		if (ReadPostData() < 0) {
			return;
		}
	}

	Buf = NewStrBuf();
	WCC->trailing_javascript = NewStrBuf();

	/* Convert base64-encoded URL's back to plain text */
	if (!strncmp(ChrPtr(WCC->Hdr->this_page), "/B64", 4)) {
		StrBufCutLeft(WCC->Hdr->this_page, 4);
		StrBufDecodeBase64(WCC->Hdr->this_page);
		http_redirect(ChrPtr(WCC->Hdr->this_page));
		goto SKIP_ALL_THIS_CRAP;
	}

	/* If there are variables in the URL, we must grab them now */
	if (WCC->Hdr->PlainArgs != NULL)
		ParseURLParams(WCC->Hdr->PlainArgs);

	/* If the client sent a nonce that is incorrect, kill the request. */
	if (havebstr("nonce")) {
		if (verbose)
			syslog(LOG_DEBUG, "Comparing supplied nonce %s to session nonce %d", 
			       bstr("nonce"), WCC->nonce
				);
		if (ibstr("nonce") != WCC->nonce) {
			syslog(LOG_INFO, "Ignoring request with mismatched nonce.");
			hprintf("HTTP/1.1 404 Security check failed\r\n");
			hprintf("Content-Type: text/plain\r\n");
			begin_burst();
			wc_printf("Security check failed.\r\n");
			end_burst();
			goto SKIP_ALL_THIS_CRAP;
		}
	}

	/*
	 * If we're not connected to a Citadel server, try to hook up the connection now.
	 */
	if (!WCC->connected) {
		if (GetConnected()) {
			hprintf("HTTP/1.1 503 Service Unavailable\r\n");
			hprintf("Content-Type: text/html\r\n");
			begin_burst();
			wc_printf("<html><head><title>503 Service Unavailable</title></head><body>\n");
			wc_printf(_("This program was unable to connect or stay "
				"connected to the Citadel server.  Please report "
				"this problem to your system administrator.")
			);
			wc_printf("<br>");
			wc_printf("<a href=\"http://www.citadel.org/doku.php/"
				"faq:generalquestions:webcit_unable_to_connect\">%s</a>",
				_("Read More...")
			);
			wc_printf("</body></html>\n");
			end_burst();
			goto SKIP_ALL_THIS_CRAP;
		}
	}

	/*
	 * If we're not logged in, but we have authentication data (either from
	 * a cookie or from http-auth), try logging in to Citadel using that.
	 */
	if (	(!WCC->logged_in)
		&& (StrLength(WCC->Hdr->c_username) > 0)
		&& (StrLength(WCC->Hdr->c_password) > 0)
	) {
		long Status;

		FlushStrBuf(Buf);
		serv_printf("USER %s", ChrPtr(WCC->Hdr->c_username));
		StrBuf_ServGetln(Buf);
		if (GetServerStatus(Buf, &Status) == 3) {
			serv_printf("PASS %s", ChrPtr(WCC->Hdr->c_password));
			StrBuf_ServGetln(Buf);
			if (GetServerStatus(Buf, NULL) == 2) {
				become_logged_in(WCC->Hdr->c_username,
						 WCC->Hdr->c_password, Buf);
			} else {
				/* Should only display when password is wrong */
				WCC->ImportantMsg = NewStrBufPlain(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
				authorization_required();
				FreeStrBuf(&Buf);
				goto SKIP_ALL_THIS_CRAP;
			}
		}
		else if (Status == 541) {
			WCC->logged_in = 1;
		}
	}

	xhttp = (WCC->Hdr->HR.eReqType != eGET) &&
		(WCC->Hdr->HR.eReqType != ePOST) &&
		(WCC->Hdr->HR.eReqType != eHEAD);

	/*
	 * If a 'go' (or 'gotofirst') parameter has been specified, attempt to goto that room
	 * prior to doing anything else.
	 */
	if (havebstr("go")) {
		int ret;
		if (verbose)
			syslog(LOG_DEBUG, "Explicit room selection: %s", bstr("go"));
		ret = gotoroom(sbstr("go"));	/* do quietly to avoid session output! */
		if ((ret/100) != 2) {
			if (verbose)
				syslog(LOG_DEBUG, "Unable to change to [%s]; Reason: %d", bstr("go"), ret);
		}
	}
	else if (havebstr("gotofirst")) {
		int ret;
		if (verbose)
			syslog(LOG_DEBUG, "Explicit room selection: %s", bstr("gotofirst"));
		ret = gotoroom(sbstr("gotofirst"));	/* do quietly to avoid session output! */
		if ((ret/100) != 2) {
			syslog(LOG_INFO, "Unable to change to [%s]; Reason: %d", bstr("gotofirst"), ret);
		}
	}

	/*
	 * If we aren't in any room yet, but we have cookie data telling us where we're
	 * supposed to be, and 'go' was not specified, then go there.
	 */
	else if ( (StrLength(WCC->CurRoom.name) == 0) && ( (StrLength(WCC->Hdr->c_roomname) > 0) )) {
		int ret;

		if (verbose)
			syslog(LOG_DEBUG, "We are in '%s' but cookie indicates '%s', going there...",
			       ChrPtr(WCC->CurRoom.name),
			       ChrPtr(WCC->Hdr->c_roomname)
		);
		ret = gotoroom(WCC->Hdr->c_roomname);	/* do quietly to avoid session output! */
		if ((ret/100) != 2) {
			if (verbose)
				syslog(LOG_DEBUG, "COOKIEGOTO: Unable to change to [%s]; Reason: %d",
				       ChrPtr(WCC->Hdr->c_roomname), ret);
		}
	}

	if (WCC->Hdr->HR.Handler != NULL) {
		if (	(!WCC->logged_in)
			&& ((WCC->Hdr->HR.Handler->Flags & ANONYMOUS) == 0)
			&& (WCC->serv_info != NULL)
			&& (WCC->serv_info->serv_supports_guest == 0)
		) {
			display_login();
		}
		else {
			if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0) {
				begin_ajax_response();
			}
			WCC->Hdr->HR.Handler->F();
			if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0) {
				end_ajax_response();
			}
		}
	}
	/* When all else fails, display the default landing page or a main menu. */
	else {
		/* 
		 * ordinary browser users get a nice login screen, DAV etc. requsets
		 * are given a 401 so they can handle it appropriate.
		 */
		if (!WCC->logged_in)  {
			if (xhttp) {
				authorization_required();
			}
			else {
				display_default_landing_page();
			}
		}
		/*
		 * Toplevel dav requests? or just a flat browser request? 
		 */
		else {
			if (xhttp) {
				dav_main();
			}
			else {
				display_main_menu();
			}
		}
	}

SKIP_ALL_THIS_CRAP:
	FreeStrBuf(&Buf);
	fflush(stdout);
}