X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fwiki%2Fserv_wiki.c;h=e5d2f545533de44f133d74e6820757ffe111bf30;hb=0387f48886a9395d89eaca01cd40ab751610426f;hp=33d856310f55e0907e9e04616239cac9af1932d3;hpb=848934c1722edc208c4df49c571586b72c3fc486;p=citadel.git diff --git a/citadel/modules/wiki/serv_wiki.c b/citadel/modules/wiki/serv_wiki.c index 33d856310..e5d2f5455 100644 --- a/citadel/modules/wiki/serv_wiki.c +++ b/citadel/modules/wiki/serv_wiki.c @@ -1,7 +1,7 @@ /* * Server-side module for Wiki rooms. This handles things like version control. * - * Copyright (c) 2009-2012 by the citadel.org team + * Copyright (c) 2009-2020 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. @@ -45,6 +45,7 @@ #include "config.h" #include "control.h" #include "user_ops.h" +#include "room_ops.h" #include "database.h" #include "msgbase.h" #include "euidindex.h" @@ -69,7 +70,7 @@ char *wwm = "9999999999.WikiWaybackMachine"; * 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; @@ -89,11 +90,14 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { 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); } @@ -101,7 +105,18 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { 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]); @@ -109,15 +124,15 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { /* 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); @@ -131,14 +146,14 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { 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); } @@ -151,13 +166,13 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { 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, @@ -220,7 +235,9 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { 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 */ @@ -301,7 +318,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { uuid, Now, CCC->user.fullname, - config.c_nodename); + CtdlGetConfigStr("c_nodename")); memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0); @@ -335,14 +352,14 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { CM_SetFieldLONG(history_msg, eTimestamp, Now); - CtdlSubmitMsg(history_msg, NULL, "", 0); + CtdlSubmitMsg(history_msg, NULL, ""); } else { syslog(LOG_ALERT, "Empty boundary string in history message. No history!\n"); } free(diffbuf); - CtdlFreeMessage(history_msg); + CM_Free(history_msg); return(0); } @@ -394,8 +411,8 @@ void wiki_history(char *pagename) { msg = NULL; } - if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) { - CtdlFreeMessage(msg); + if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) { + CM_Free(msg); msg = NULL; } @@ -406,10 +423,10 @@ void wiki_history(char *pagename) { 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; } @@ -526,8 +543,8 @@ void wiki_rev(char *pagename, char *rev, char *operation) msg = NULL; } - if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) { - CtdlFreeMessage(msg); + if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) { + CM_Free(msg); msg = NULL; } @@ -541,13 +558,13 @@ void wiki_rev(char *pagename, char *rev, char *operation) 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)); + syslog(LOG_ERR, "%s: %m", temp); } - CtdlFreeMessage(msg); + CM_Free(msg); /* Get the revision history */ @@ -560,8 +577,8 @@ void wiki_rev(char *pagename, char *rev, char *operation) msg = NULL; } - if ((msg != NULL) && (msg->cm_fields[eMesageText] == NULL)) { - CtdlFreeMessage(msg); + if ((msg != NULL) && CM_IsEmpty(msg, eMesageText)) { + CM_Free(msg); msg = NULL; } @@ -579,8 +596,8 @@ void wiki_rev(char *pagename, char *rev, char *operation) 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) { @@ -616,7 +633,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) else if (!strcasecmp(operation, "fetch")) { CM_SetField(msg, eAuthor, HKEY("Citadel")); CtdlCreateRoom(wwm, 5, "", 0, 1, 1, VIEW_BBS); /* Not an error if already exists */ - msgnum = CtdlSubmitMsg(msg, NULL, wwm, 0); /* Store the revision here */ + msgnum = CtdlSubmitMsg(msg, NULL, wwm); /* Store the revision here */ /* * WARNING: VILE SLEAZY HACK @@ -638,18 +655,28 @@ void wiki_rev(char *pagename, char *rev, char *operation) } 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)); - msgnum = CtdlSubmitMsg(msg, NULL, "", 0); /* Replace the current revision */ + 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)); + } + + if (!IsEmptyStr(pagename)) { + CM_SetField(msg, eExclusiveID, pagename, strlen(pagename)); + } + msgnum = CtdlSubmitMsg(msg, NULL, ""); /* 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 */ }