Move another message into the only file its used.
[citadel.git] / citadel / modules / network / serv_netspool.c
index 500d931bf0c57cce635bb116a0283449fe8956ac..04144b54267317ffc1303d8aed8ddd090a3dbbe0 100644 (file)
 #endif
 
 
+/*
+ * Bounce a message back to the sender
+ */
+void network_bounce(struct CtdlMessage *msg, char *reason)
+{
+       struct CitContext *CCC = CC;
+       char buf[SIZ];
+       char bouncesource[SIZ];
+       char recipient[SIZ];
+       recptypes *valid = NULL;
+       char force_room[ROOMNAMELEN];
+       static int serialnum = 0;
+       long len;
+
+       QNM_syslog(LOG_DEBUG, "entering network_bounce()\n");
+
+       if (msg == NULL) return;
+
+       snprintf(bouncesource, sizeof bouncesource, "%s@%s", BOUNCESOURCE, config.c_nodename);
+
+       /* 
+        * Give it a fresh message ID
+        */
+       len = snprintf(buf, sizeof(buf),
+                      "%ld.%04lx.%04x@%s",
+                      (long)time(NULL),
+                      (long)getpid(),
+                      ++serialnum,
+                      config.c_fqdn);
+
+       CM_SetField(msg, emessageId, buf, len);
+
+       /*
+        * FIXME ... right now we're just sending a bounce; we really want to
+        * include the text of the bounced message.
+        */
+       CM_SetField(msg, eMesageText, reason, strlen(reason));
+       msg->cm_format_type = 0;
+
+       /*
+        * Turn the message around
+        */
+       CM_FlushField(msg, eRecipient);
+       CM_FlushField(msg, eDestination);
+
+       len = snprintf(recipient, sizeof(recipient), "%s@%s",
+                      msg->cm_fields[eAuthor],
+                      msg->cm_fields[eNodeName]);
+
+       CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE));
+       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
+
+       Netmap_AddMe(msg, HKEY("unknown_user"));
+
+       /* Now submit the message */
+       valid = validate_recipients(recipient, NULL, 0);
+       if (valid != NULL) if (valid->num_error != 0) {
+               free_recipients(valid);
+               valid = NULL;
+       }
+       if ( (valid == NULL) || (!strcasecmp(recipient, bouncesource)) ) {
+               strcpy(force_room, config.c_aideroom);
+       }
+       else {
+               strcpy(force_room, "");
+       }
+       if ( (valid == NULL) && IsEmptyStr(force_room) ) {
+               strcpy(force_room, config.c_aideroom);
+       }
+       CtdlSubmitMsg(msg, valid, force_room, 0);
+
+       /* Clean up */
+       if (valid != NULL) free_recipients(valid);
+       CM_Free(msg);
+       QNM_syslog(LOG_DEBUG, "leaving network_bounce()\n");
+}
+
+
 void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
        RoomNetCfgLine *nptr;
@@ -182,6 +261,7 @@ void InspectQueuedRoom(SpoolControl **pSC,
                       HashList *working_ignetcfg,
                       HashList *the_netmap)
 {
+       struct CitContext *CCC = CC;
        SpoolControl *sc;
        int i = 0;
 
@@ -204,7 +284,7 @@ void InspectQueuedRoom(SpoolControl **pSC,
        }
        if (sc->room.QRhighest <= sc->lastsent)
        {
-               syslog(LOG_DEBUG, "nothing to do for <%s>\n", room_to_spool->name);
+               QN_syslog(LOG_DEBUG, "nothing to do for <%s>\n", room_to_spool->name);
                free(sc);
                return;
        }
@@ -353,16 +433,6 @@ void network_spoolout_room(SpoolControl *sc)
 
        syslog(LOG_INFO, "Networking started for <%s>\n", CCC->room.QRname);
 
-       /* If there are digest recipients, we have to build a digest */
-       if (sc->Users[digestrecp] != NULL) {
-               
-               sc->digestfp = create_digest_file(&sc->room);
-               sc->haveDigest = ftell(sc->digestfp) > 0;
-               if (!sc->haveDigest) {
-                       fprintf(sc->digestfp, "Content-type: text/plain\n\n");
-               }
-       }
-
        CalcListID(sc);
 
        /* remember where we started... */
@@ -394,7 +464,7 @@ void network_spoolout_room(SpoolControl *sc)
 
 
        /* If we wrote a digest, deliver it and then close it */
-       if (sc->digestfp != NULL) {
+       if (sc->Users[digestrecp] != NULL) {
                time_t now = time(NULL);
                time_t secs_today = now % (24 * 60 * 60);
                long delta = 0;
@@ -404,25 +474,31 @@ void network_spoolout_room(SpoolControl *sc)
                        delta = (24 * 60 * 60) - delta;
                }
 
-               if (sc->haveDigest     &&
-                   (secs_today < 300) && 
-                   (delta < 300) )
+               if ((secs_today < 300) && 
+                   (delta < 300))
                {
-                       last_digest_delivery = now;
-                       fprintf(sc->digestfp,
-                               " -----------------------------------"
-                               "------------------------------------"
-                               "-------\n"
-                               "You are subscribed to the '%s' "
-                               "list.\n"
-                               "To post to the list: %s\n",
-                               CCC->room.QRname, buf
-                               );
-                       network_deliver_digest(sc);     /* deliver */
+                       if (sc->digestfp == NULL) {
+                               sc->digestfp = create_digest_file(&sc->room, 0);
+                       }
+                       if (sc->digestfp != NULL) {
+                               last_digest_delivery = now;
+                               fprintf(sc->digestfp,
+                                       " -----------------------------------"
+                                       "------------------------------------"
+                                       "-------\n"
+                                       "You are subscribed to the '%s' "
+                                       "list.\n"
+                                       "To post to the list: %s\n",
+                                       CCC->room.QRname, buf
+                                       );
+                               network_deliver_digest(sc);     /* deliver */
+                               remove_digest_file(&sc->room);
+                       }
                }
+       }
+       if (sc->digestfp != NULL) {
                fclose(sc->digestfp);
                sc->digestfp = NULL;
-               remove_digest_file(&sc->room);
        }
 
        /* Now rewrite the config file */
@@ -437,6 +513,53 @@ void network_spoolout_room(SpoolControl *sc)
        }
 }
 
+
+/*
+ * Check the use table.  This is a list of messages which have recently
+ * arrived on the system.  It is maintained and queried to prevent the same
+ * message from being entered into the database multiple times if it happens
+ * to arrive multiple times by accident.
+ */
+int network_usetable(struct CtdlMessage *msg)
+{
+       StrBuf *msgid;
+       struct CitContext *CCC = CC;
+       time_t now;
+
+       /* Bail out if we can't generate a message ID */
+       if ((msg == NULL) || CM_IsEmpty(msg, emessageId))
+       {
+               return(0);
+       }
+
+       /* Generate the message ID */
+       msgid = NewStrBufPlain(CM_KEY(msg, emessageId));
+       if (haschar(ChrPtr(msgid), '@') == 0) {
+               StrBufAppendBufPlain(msgid, HKEY("@"), 0);
+               if (!CM_IsEmpty(msg, eNodeName)) {
+                       StrBufAppendBufPlain(msgid, CM_KEY(msg, eNodeName), 0);
+               }
+               else {
+                       FreeStrBuf(&msgid);
+                       return(0);
+               }
+       }
+       now = time(NULL);
+       if (CheckIfAlreadySeen("Networker Import",
+                              msgid,
+                              now, 0,
+                              eCheckUpdate,
+                              CCC->cs_pid, 0) != 0)
+       {
+               FreeStrBuf(&msgid);
+               return(1);
+       }
+       FreeStrBuf(&msgid);
+
+       return(0);
+}
+
+
 /*
  * Process a buffer containing a single message from a single file
  * from the inbound queue