>>> On May 9, 2006, at 12:57 PM, Jeremy Kitchen wrote:
>>>> the problem is that vpopmail is using qmail-inject to forward
>>>> messages.
>>>> qmail-inject does not tolerate malformed messages.
>>>>
>>>> it's that simple.
>>>
>>> Any volunteers to review the code in vdelivermail.c and modify it to
>>> use qmail-queue instead of qmail-inject?
>>>
>> OK, here's a quick stab at a basic patch - I modified qmail_inject_open
>> to
>> open qmail-queue appropriately (no args), and changed deliver_mail to
>> talk
>> to it.  I THINK :)
>>
>> There's no bounds checking and so forth in here, there are a few places
>> where there really needs to be some extra code to make sure that the
>> data
>> acquired is valid, but it's designed to be proof-of-concept.  It
>> compiles,
>> but that's all I can guarantee.
>>
>> Use at your own risk, yada yada...  Feel free to modify it as needed, I
>> have no ego attached to this code :)
>>
> OK, so I can't stand writing sloppy code :)  Here's an updated version of
> the patch that handles things a little better (albeit in a slightly more
> complicated manner), and cleans up a couple remaining stragglers of the
> changeover.
>
And here's another update.  I realized as I was driving home last night
that I'd made a mistake (that's what I get for coding while tired :)) and
was printing double NULLs in the envelope.  This fixes it (and simplifies
the code a little too).

Josh
-- 
Joshua Megerman
SJGames MIB #5273 - OGRE AI Testing Division
You can't win; You can't break even; You can't even quit the game.
  - Layman's translation of the Laws of Thermodynamics
--- vdelivermail.c.orig	2006-05-09 17:35:00.000000000 -0400
+++ vdelivermail.c	2006-05-10 09:09:19.000000000 -0400
@@ -72,6 +72,7 @@
 
 #define BUFF_SIZE 300
 int fdm;
+int fde;
 
 #define EXIT_BOUNCE 100
 #define EXIT_DEFER 111
@@ -304,33 +305,41 @@
 }
 #endif
 
-/* Forks off qmail-inject.  Returns PID of child, or 0 for failure. */
-pid_t qmail_inject_open(char *address)
+/* Forks off qmail-queue.  Returns PID of child, or 0 for failure. */
+pid_t qmail_queue_open()
 {
  int pim[2];
+ int pie[2];
+
  pid_t pid;
- static char *binqqargs[4];
+ static char *binqqargs[2];
 
     if ( pipe(pim) == -1) return 0;
+    if ( pipe(pie) == -1) return 0;
 
     switch(pid=vfork()){
       case -1:
         close(pim[0]);
         close(pim[1]);
+        close(pie[0]);
+        close(pie[1]);
         printf ("Unable to fork: %d.", errno);
         return 0;
       case 0:
         close(pim[1]);
+        close(pie[1]);
         if (vfd_move(0,pim[0]) == -1 ) _exit(-1);
+        if (vfd_move(1,pie[0]) == -1 ) _exit(-1);
         binqqargs[0] = QMAILINJECT;
-        binqqargs[1] = "--";
-        binqqargs[2] = (*address == '&' ? &address[1] : &address[0]);
+        binqqargs[1] = 0;
         execv(*binqqargs, binqqargs);
-        printf ("Unable to launch qmail-inject.");
+        printf ("Unable to launch qmail-queue.");
         exit (EXIT_DEFER);    /* child's exit caught later */
     }
     fdm = pim[1];
+    fde = pie[1];
     close(pim[0]);
+    close(pie[0]);
     return(pid);
 }
 
@@ -628,10 +637,18 @@
       char *dtline;
       char *atpos;
       int dtlen;
+      char *sender = 0;
+      char keychar[2] = { 'F', 'T' };
+      char *envptrs[4] = { keychar, sender, keychar+1, address };
+      int envlens[4] = { 1, 0, 1, 0 }; // sender and address get initialized later
+      int writestr;
 
       if (*address=='&') ++address;  /* will this case ever happen? */
-      inject_pid = qmail_inject_open(address);
-      if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-inject");
+      envptrs[3] = address;
+      envlens[3] = strlen(address) + 1;
+
+      inject_pid = qmail_queue_open();
+      if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-queue");
       
       /* use the DTLINE variable, but skip past the dash in 
        * [EMAIL PROTECTED] 
@@ -665,13 +682,33 @@
       }
       
       if (fdcopy (fdm, 0, DeliveredTo, strlen(DeliveredTo)) != 0) {
-          printf ("write to qmail-inject failed: %d\n", errno);
+          printf ("write to qmail-queue failed: %d\n", errno);
           close(fdm);
+          close(fde);
           waitpid(inject_pid,&child,0);
           vexiterr (EXIT_DEFER, "system error");
       }
 
+      if (!(sender = getenv("SENDER"))) {
+          printf ("unable to acquire SENDER from environment\n");
+          close(fdm);
+          close(fde);
+          vexiterr (EXIT_DEFER, "system error");
+      }
+      envptrs[1] = sender;
+      envlens[1] = strlen(sender) + 1;
+
+      for (writestr = 0; writestr < 4; writestr++) {
+        if ((write(fde, (void *)envptrs[writestr], envlens[writestr])) != envlens[writestr]) {
+            printf ("write to qmail-queue failed: %d\n", errno);
+            close(fdm);
+            close(fde);
+            vexiterr (EXIT_DEFER, "system error");
+        }
+      }
+
       close(fdm);
+      close(fde);
       waitpid(inject_pid,&child,0);
       if (wait_exitcode(child) == 0) return;
       vexiterr (EXIT_DEFER, "system error");

Reply via email to