/*
* Server-side module for Wiki rooms. This handles things like version control.
*
- * Copyright (c) 2009-2012 by the citadel.org team
+ * Copyright (c) 2009-2015 by the citadel.org team
*
* This program is open source software. You can redistribute it and/or
* modify it under the terms of the GNU General Public License, version 3.
#include "config.h"
#include "control.h"
#include "user_ops.h"
+#include "room_ops.h"
#include "database.h"
#include "msgbase.h"
#include "euidindex.h"
* Before allowing a wiki page save to execute, we have to perform version control.
* This involves fetching the old version of the page if it exists.
*/
-int wiki_upload_beforesave(struct CtdlMessage *msg) {
+int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) {
struct CitContext *CCC = CC;
long old_msgnum = (-1L);
struct CtdlMessage *old_msg = NULL;
char *diffbuf = NULL;
size_t diffbuf_len = 0;
char *ptr = NULL;
+ long newmsgid;
+ StrBuf *msgidbuf;
if (!CCC->logged_in) return(0); /* Only do this if logged in. */
/* Is this a room with a Wiki in it, don't run this hook. */
- if (CCC->room.QRdefaultview != VIEW_WIKI) {
+ if ((CCC->room.QRdefaultview != VIEW_WIKI) &&
+ (CCC->room.QRdefaultview != VIEW_WIKIMD)) {
return(0);
}
if (msg->cm_format_type != 4) return(0);
/* If there's no EUID we can't do this. Reject the post. */
- if (msg->cm_fields[eExclusiveID] == NULL) return(1);
+ if (CM_IsEmpty(msg, eExclusiveID)) return(1);
+
+ newmsgid = get_new_message_number();
+ msgidbuf = NewStrBuf();
+ StrBufPrintf(msgidbuf, "%08lX-%08lX@%s/%s",
+ (long unsigned int) time(NULL),
+ (long unsigned int) newmsgid,
+ CtdlGetConfigStr("c_fqdn"),
+ msg->cm_fields[eExclusiveID]
+ );
+
+ CM_SetAsFieldSB(msg, emessageId, &msgidbuf);
history_page_len = snprintf(history_page, sizeof history_page,
"%s_HISTORY_", msg->cm_fields[eExclusiveID]);
/* Make sure we're saving a real wiki page rather than a wiki history page.
* This is important in order to avoid recursing infinitely into this hook.
*/
- if ( (strlen(msg->cm_fields[eExclusiveID]) >= 9)
- && (!strcasecmp(&msg->cm_fields[eExclusiveID][strlen(msg->cm_fields[eExclusiveID])-9], "_HISTORY_"))
+ if ( (msg->cm_lengths[eExclusiveID] >= 9)
+ && (!strcasecmp(&msg->cm_fields[eExclusiveID][msg->cm_lengths[eExclusiveID]-9], "_HISTORY_"))
) {
syslog(LOG_DEBUG, "History page not being historied\n");
return(0);
}
/* If there's no message text, obviously this is all b0rken and shouldn't happen at all */
- if (msg->cm_fields[eMesageText] == NULL) return(0);
+ if (CM_IsEmpty(msg, eMesageText)) return(0);
/* Set the message subject identical to the page name */
CM_CopyField(msg, eMsgSubject, eExclusiveID);
/* See if we can retrieve the previous version. */
old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room);
if (old_msgnum > 0L) {
- old_msg = CtdlFetchMessage(old_msgnum, 1);
+ old_msg = CtdlFetchMessage(old_msgnum, 1, 1);
}
else {
old_msg = NULL;
}
- if ((old_msg != NULL) && (old_msg->cm_fields[eMesageText] == NULL)) { /* old version is corrupt? */
- CtdlFreeMessage(old_msg);
+ if ((old_msg != NULL) && (CM_IsEmpty(old_msg, eMesageText))) { /* old version is corrupt? */
+ CM_Free(old_msg);
old_msg = NULL;
}
/* If no changes were made, don't bother saving it again */
if ((old_msg != NULL) && (!strcmp(msg->cm_fields[eMesageText], old_msg->cm_fields[eMesageText]))) {
- CtdlFreeMessage(old_msg);
+ CM_Free(old_msg);
return(1);
}
if (old_msg != NULL) {
fp = fopen(diff_old_filename, "w");
- rv = fwrite(old_msg->cm_fields[eMesageText], strlen(old_msg->cm_fields[eMesageText]), 1, fp);
+ rv = fwrite(old_msg->cm_fields[eMesageText], old_msg->cm_lengths[eMesageText], 1, fp);
fclose(fp);
- CtdlFreeMessage(old_msg);
+ CM_Free(old_msg);
}
fp = fopen(diff_new_filename, "w");
- rv = fwrite(msg->cm_fields[eMesageText], strlen(msg->cm_fields[eMesageText]), 1, fp);
+ rv = fwrite(msg->cm_fields[eMesageText], msg->cm_lengths[eMesageText], 1, fp);
fclose(fp);
snprintf(diff_cmd, sizeof diff_cmd,
history_msgnum = CtdlLocateMessageByEuid(history_page, &CCC->room);
history_msg = NULL;
if (history_msgnum > 0L) {
- history_msg = CtdlFetchMessage(history_msgnum, 1);
+ history_msg = CtdlFetchMessage(history_msgnum, 1, 1);
}
/* Create a new history message if necessary */
history_msg->cm_anon_type = MES_NORMAL;
history_msg->cm_format_type = FMT_RFC822;
CM_SetField(history_msg, eAuthor, HKEY("Citadel"));
- CM_SetField(history_msg, eRecipient, CCC->room.QRname, strlen(CCC->room.QRname));
+ if (!IsEmptyStr(CCC->room.QRname)){
+ CM_SetField(history_msg, eRecipient, CCC->room.QRname, strlen(CCC->room.QRname));
+ }
CM_SetField(history_msg, eExclusiveID, history_page, history_page_len);
CM_SetField(history_msg, eMsgSubject, history_page, history_page_len);
CM_SetField(history_msg, eSuppressIdx, HKEY("1")); /* suppress full text indexing */
uuid,
Now,
CCC->user.fullname,
- config.c_nodename);
+ CtdlGetConfigStr("c_nodename"));
memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0);
}
free(diffbuf);
- CtdlFreeMessage(history_msg);
+ CM_Free(history_msg);
return(0);
}
snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename);
msgnum = CtdlLocateMessageByEuid(history_page_name, &CC->room);
if (msgnum > 0L) {
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
}
else {
msg = NULL;
}
- if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) {
- CtdlFreeMessage(msg);
+ if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) {
+ CM_Free(msg);
msg = NULL;
}
cprintf("%d Revision history for '%s'\n", LISTING_FOLLOWS, pagename);
- mime_parser(msg->cm_fields[eMesageText], NULL, *wiki_history_callback, NULL, NULL, NULL, 0);
+ mime_parser(CM_RANGE(msg, eMesageText), *wiki_history_callback, NULL, NULL, NULL, 0);
cprintf("000\n");
- CtdlFreeMessage(msg);
+ CM_Free(msg);
return;
}
*/
msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room);
if (msgnum > 0L) {
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
}
else {
msg = NULL;
}
- if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) {
- CtdlFreeMessage(msg);
+ if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) {
+ CM_Free(msg);
msg = NULL;
}
CtdlMakeTempFileName(temp, sizeof temp);
fp = fopen(temp, "w");
if (fp != NULL) {
- r = fwrite(msg->cm_fields[eMesageText], strlen(msg->cm_fields[eMesageText]), 1, fp);
+ r = fwrite(msg->cm_fields[eMesageText], msg->cm_lengths[eMesageText], 1, fp);
fclose(fp);
}
else {
syslog(LOG_ALERT, "Cannot open %s: %s\n", temp, strerror(errno));
}
- CtdlFreeMessage(msg);
+ CM_Free(msg);
/* Get the revision history */
snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename);
msgnum = CtdlLocateMessageByEuid(history_page_name, &CCC->room);
if (msgnum > 0L) {
- msg = CtdlFetchMessage(msgnum, 1);
+ msg = CtdlFetchMessage(msgnum, 1, 1);
}
else {
msg = NULL;
}
- if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) {
- CtdlFreeMessage(msg);
+ if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) {
+ CM_Free(msg);
msg = NULL;
}
hecbd.stop_when = rev;
striplt(hecbd.stop_when);
- mime_parser(msg->cm_fields[eMesageText], NULL, *wiki_rev_callback, NULL, NULL, (void *)&hecbd, 0);
- CtdlFreeMessage(msg);
+ mime_parser(CM_RANGE(msg, eMesageText), *wiki_rev_callback, NULL, NULL, (void *)&hecbd, 0);
+ CM_Free(msg);
/* Were we successful? */
if (hecbd.done == 0) {
}
else if (!strcasecmp(operation, "revert")) {
CM_SetFieldLONG(msg, eTimestamp, time(NULL));
- CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
- CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email));
- CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
- CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME));
- CM_SetField(msg, eExclusiveID, pagename, strlen(pagename));
+ if (!IsEmptyStr(CCC->user.fullname)) {
+ CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
+ }
+
+ if (!IsEmptyStr(CCC->cs_inet_email)) {
+ CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email));
+ }
+
+ if (!IsEmptyStr(CCC->room.QRname)) {
+ CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
+ }
+
+ CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
+
+ if (!IsEmptyStr(pagename)) {
+ CM_SetField(msg, eExclusiveID, pagename, strlen(pagename));
+ }
msgnum = CtdlSubmitMsg(msg, NULL, "", 0); /* Replace the current revision */
}
else {
/* Theoretically it is impossible to get here, but throw an error anyway */
msgnum = (-1L);
}
- CtdlFreeMessage(msg);
+ CM_Free(msg);
if (msgnum >= 0L) {
cprintf("%d %ld\n", CIT_OK, msgnum); /* Give the client a msgnum */
}