This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / sendmail / src / queue.c
index c9cd073..5c4a027 100644 (file)
 
 #ifndef lint
 #ifdef QUEUE
 
 #ifndef lint
 #ifdef QUEUE
-static char sccsid[] = "@(#)queue.c    8.1 (Berkeley) 6/7/93 (with queueing)";
+static char sccsid[] = "@(#)queue.c    8.27 (Berkeley) 10/29/93 (with queueing)";
 #else
 #else
-static char sccsid[] = "@(#)queue.c    8.1 (Berkeley) 6/7/93 (without queueing)";
+static char sccsid[] = "@(#)queue.c    8.27 (Berkeley) 10/29/93 (without queueing)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
-# include <signal.h>
 # include <errno.h>
 # include <pwd.h>
 # include <dirent.h>
 # include <errno.h>
 # include <pwd.h>
 # include <dirent.h>
@@ -101,43 +100,68 @@ queueup(e, queueall, announce)
        **  Create control file.
        */
 
        **  Create control file.
        */
 
-       newid = (e->e_id == NULL);
+       newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags);
+
+       /* if newid, queuename will create a locked qf file in e->lockfp */
        strcpy(tf, queuename(e, 't'));
        tfp = e->e_lockfp;
        if (tfp == NULL)
                newid = FALSE;
        strcpy(tf, queuename(e, 't'));
        tfp = e->e_lockfp;
        if (tfp == NULL)
                newid = FALSE;
-       if (newid)
-       {
-               tfp = e->e_lockfp;
-       }
-       else
+
+       /* if newid, just write the qf file directly (instead of tf file) */
+       if (!newid)
        {
                /* get a locked tf file */
        {
                /* get a locked tf file */
-               for (i = 100; --i >= 0; )
+               for (i = 0; i < 128; i++)
                {
                        fd = open(tf, O_CREAT|O_WRONLY|O_EXCL, FileMode);
                        if (fd < 0)
                        {
                {
                        fd = open(tf, O_CREAT|O_WRONLY|O_EXCL, FileMode);
                        if (fd < 0)
                        {
-                               if (errno == EEXIST)
-                                       continue;
-notemp:
-                               syserr("!queueup: cannot create temp file %s", tf);
+                               if (errno != EEXIST)
+                                       break;
+#ifdef LOG
+                               if (LogLevel > 0 && (i % 32) == 0)
+                                       syslog(LOG_ALERT, "queueup: cannot create %s: %s",
+                                               tf, errstring(errno));
+#endif
+                               continue;
                        }
 
                        }
 
-                       if (lockfile(fd, tf, LOCK_EX|LOCK_NB))
+                       if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB))
                                break;
                                break;
+#ifdef LOG
+                       else if (LogLevel > 0 && (i % 32) == 0)
+                               syslog(LOG_ALERT, "queueup: cannot lock %s: %s",
+                                       tf, errstring(errno));
+#endif
 
                        close(fd);
 
                        close(fd);
-                       sleep(i);
-               }
-               if (fd < 0)
-                       goto notemp;
 
 
-               tfp = fdopen(fd, "w");
+                       if ((i % 32) == 31)
+                       {
+                               /* save the old temp file away */
+                               (void) rename(tf, queuename(e, 'T'));
+                       }
+                       else
+                               sleep(i % 32);
+               }
+               if (fd < 0 || (tfp = fdopen(fd, "w")) == NULL)
+                       syserr("!queueup: cannot create queue temp file %s", tf);
        }
 
        if (tTd(40, 1))
        }
 
        if (tTd(40, 1))
-               printf("queueing %s\n", e->e_id);
+               printf("\n>>>>> queueing %s%s >>>>>\n", e->e_id,
+                       newid ? " (new id)" : "");
+       if (tTd(40, 9))
+       {
+               printf("  tfp=");
+               dumpfd(fileno(tfp), TRUE, FALSE);
+               printf("  lockfp=");
+               if (e->e_lockfp == NULL)
+                       printf("NULL\n");
+               else
+                       dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
+       }
 
        /*
        **  If there is no data file yet, create one.
 
        /*
        **  If there is no data file yet, create one.
@@ -148,11 +172,12 @@ notemp:
                register FILE *dfp;
                extern putbody();
 
                register FILE *dfp;
                extern putbody();
 
-               e->e_df = newstr(queuename(e, 'd'));
+               e->e_df = queuename(e, 'd');
+               e->e_df = newstr(e->e_df);
                fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode);
                fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode);
-               if (fd < 0)
-                       syserr("!queueup: cannot create %s", e->e_df);
-               dfp = fdopen(fd, "w");
+               if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL)
+                       syserr("!queueup: cannot create data temp file %s",
+                               e->e_df);
                (*e->e_putbody)(dfp, FileMailer, e, NULL);
                (void) xfclose(dfp, "queueup dfp", e->e_id);
                e->e_putbody = putbody;
                (*e->e_putbody)(dfp, FileMailer, e, NULL);
                (void) xfclose(dfp, "queueup dfp", e->e_id);
                e->e_putbody = putbody;
@@ -224,7 +249,7 @@ notemp:
                                e->e_to = q->q_paddr;
                                message("queued");
                                if (LogLevel > 8)
                                e->e_to = q->q_paddr;
                                message("queued");
                                if (LogLevel > 8)
-                                       logdelivery(NULL, NULL, "queued", e);
+                                       logdelivery(NULL, NULL, "queued", NULL, e);
                                e->e_to = NULL;
                        }
                        if (tTd(40, 1))
                                e->e_to = NULL;
                        }
                        if (tTd(40, 1))
@@ -247,7 +272,7 @@ notemp:
 
        bzero((char *) &nullmailer, sizeof nullmailer);
        nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
 
        bzero((char *) &nullmailer, sizeof nullmailer);
        nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
-                       nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1;
+                       nullmailer.m_se_rwset = nullmailer.m_sh_rwset = 0;
        nullmailer.m_eol = "\n";
 
        define('g', "\201f", e);
        nullmailer.m_eol = "\n";
 
        define('g', "\201f", e);
@@ -287,12 +312,17 @@ notemp:
                else if (bitset(H_FROM|H_RCPT, h->h_flags))
                {
                        bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
                else if (bitset(H_FROM|H_RCPT, h->h_flags))
                {
                        bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
+                       FILE *savetrace = TrafficLogFile;
+
+                       TrafficLogFile = NULL;
 
                        if (bitset(H_FROM, h->h_flags))
                                oldstyle = FALSE;
 
                        commaize(h, h->h_value, tfp, oldstyle,
                                 &nullmailer, e);
 
                        if (bitset(H_FROM, h->h_flags))
                                oldstyle = FALSE;
 
                        commaize(h, h->h_value, tfp, oldstyle,
                                 &nullmailer, e);
+
+                       TrafficLogFile = savetrace;
                }
                else
                        fprintf(tfp, "%s: %s\n", h->h_field, h->h_value);
                }
                else
                        fprintf(tfp, "%s: %s\n", h->h_field, h->h_value);
@@ -302,9 +332,7 @@ notemp:
        **  Clean up.
        */
 
        **  Clean up.
        */
 
-       fflush(tfp);
-       fsync(fileno(tfp));
-       if (ferror(tfp))
+       if (fflush(tfp) < 0 || fsync(fileno(tfp)) < 0 || ferror(tfp))
        {
                if (newid)
                        syserr("!552 Error writing control file %s", tf);
        {
                if (newid)
                        syserr("!552 Error writing control file %s", tf);
@@ -314,9 +342,12 @@ notemp:
 
        if (!newid)
        {
 
        if (!newid)
        {
+               /* rename (locked) tf to be (locked) qf */
                qf = queuename(e, 'q');
                if (rename(tf, qf) < 0)
                        syserr("cannot rename(%s, %s), df=%s", tf, qf, e->e_df);
                qf = queuename(e, 'q');
                if (rename(tf, qf) < 0)
                        syserr("cannot rename(%s, %s), df=%s", tf, qf, e->e_df);
+
+               /* close and unlock old (locked) qf */
                if (e->e_lockfp != NULL)
                        (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id);
                e->e_lockfp = tfp;
                if (e->e_lockfp != NULL)
                        (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id);
                e->e_lockfp = tfp;
@@ -324,12 +355,16 @@ notemp:
        else
                qf = tf;
        errno = 0;
        else
                qf = tf;
        errno = 0;
+       e->e_flags |= EF_INQUEUE;
 
 # ifdef LOG
        /* save log info */
        if (LogLevel > 79)
                syslog(LOG_DEBUG, "%s: queueup, qf=%s, df=%s\n", e->e_id, qf, e->e_df);
 # endif /* LOG */
 
 # ifdef LOG
        /* save log info */
        if (LogLevel > 79)
                syslog(LOG_DEBUG, "%s: queueup, qf=%s, df=%s\n", e->e_id, qf, e->e_df);
 # endif /* LOG */
+
+       if (tTd(40, 1))
+               printf("<<<<< done queueing %s <<<<<\n\n", e->e_id);
        return;
 }
 
        return;
 }
 
@@ -345,7 +380,7 @@ printctladdr(a, tfp)
        static uid_t lastuid;
 
        /* initialization */
        static uid_t lastuid;
 
        /* initialization */
-       if (a == NULL || tfp == NULL)
+       if (a == NULL || a->q_alias == NULL || tfp == NULL)
        {
                if (lastctladdr != NULL && tfp != NULL)
                        fprintf(tfp, "C\n");
        {
                if (lastctladdr != NULL && tfp != NULL)
                        fprintf(tfp, "C\n");
@@ -360,10 +395,7 @@ printctladdr(a, tfp)
                uid = 0;
        else
                uid = q->q_uid;
                uid = 0;
        else
                uid = q->q_uid;
-
-       /* if a is an alias, use that for printing */
-       if (a->q_alias != NULL)
-               a = a->q_alias;
+       a = a->q_alias;
 
        /* check to see if this is the same as last time */
        if (lastctladdr != NULL && uid == lastuid &&
 
        /* check to see if this is the same as last time */
        if (lastctladdr != NULL && uid == lastuid &&
@@ -439,7 +471,7 @@ runqueue(forkflag)
 #ifndef SIGCHLD
                        (void) waitfor(pid);
 #else /* SIGCHLD */
 #ifndef SIGCHLD
                        (void) waitfor(pid);
 #else /* SIGCHLD */
-                       (void) signal(SIGCHLD, reapchild);
+                       (void) setsignal(SIGCHLD, reapchild);
 #endif /* SIGCHLD */
                        if (QueueIntvl != 0)
                                (void) setevent(QueueIntvl, runqueue, TRUE);
 #endif /* SIGCHLD */
                        if (QueueIntvl != 0)
                                (void) setevent(QueueIntvl, runqueue, TRUE);
@@ -450,7 +482,7 @@ runqueue(forkflag)
                if (fork() != 0)
                        exit(EX_OK);
 #else /* SIGCHLD */
                if (fork() != 0)
                        exit(EX_OK);
 #else /* SIGCHLD */
-               (void) signal(SIGCHLD, SIG_DFL);
+               (void) setsignal(SIGCHLD, SIG_DFL);
 #endif /* SIGCHLD */
        }
 
 #endif /* SIGCHLD */
        }
 
@@ -470,6 +502,9 @@ runqueue(forkflag)
        clrdaemon();
 # endif /* DAEMON */
 
        clrdaemon();
 # endif /* DAEMON */
 
+       /* force it to run expensive jobs */
+       NoConnect = FALSE;
+
        /*
        **  Create ourselves an envelope
        */
        /*
        **  Create ourselves an envelope
        */
@@ -512,7 +547,12 @@ runqueue(forkflag)
                }
                else
                {
                }
                else
                {
-                       dowork(w->w_name + 2, ForkQueueRuns, FALSE, e);
+                       pid_t pid;
+                       extern pid_t dowork();
+
+                       pid = dowork(w->w_name + 2, ForkQueueRuns, FALSE, e);
+                       errno = 0;
+                       (void) waitfor(pid);
                }
                free(w->w_name);
                free((char *) w);
                }
                free(w->w_name);
                free((char *) w);
@@ -592,6 +632,7 @@ orderq(doall)
        while ((d = readdir(f)) != NULL)
        {
                FILE *cf;
        while ((d = readdir(f)) != NULL)
        {
                FILE *cf;
+               register char *p;
                char lbuf[MAXNAME];
                extern bool strcontainedin();
 
                char lbuf[MAXNAME];
                extern bool strcontainedin();
 
@@ -608,8 +649,16 @@ orderq(doall)
                **  both old and new type ids.
                */
 
                **  both old and new type ids.
                */
 
-               i = strlen(d->d_name);
-               if (i != 9 && i != 10)
+               p = d->d_name + 2;
+               if (isupper(p[0]) && isupper(p[2]))
+                       p += 3;
+               else if (isupper(p[1]))
+                       p += 2;
+               else
+                       p = d->d_name;
+               for (i = 0; isdigit(*p); p++)
+                       i++;
+               if (i < 5 || *p != '\0')
                {
                        if (Verbose)
                                printf("orderq: bogus qf name %s\n", d->d_name);
                {
                        if (Verbose)
                                printf("orderq: bogus qf name %s\n", d->d_name);
@@ -770,19 +819,20 @@ workcmpf(a, b)
 **             e - the envelope in which to run it.
 **
 **     Returns:
 **             e - the envelope in which to run it.
 **
 **     Returns:
-**             none.
+**             process id of process that is running the queue job.
 **
 **     Side Effects:
 **             The work request is satisfied if possible.
 */
 
 **
 **     Side Effects:
 **             The work request is satisfied if possible.
 */
 
+pid_t
 dowork(id, forkflag, requeueflag, e)
        char *id;
        bool forkflag;
        bool requeueflag;
        register ENVELOPE *e;
 {
 dowork(id, forkflag, requeueflag, e)
        char *id;
        bool forkflag;
        bool requeueflag;
        register ENVELOPE *e;
 {
-       register int i;
+       register pid_t pid;
        extern bool readqf();
 
        if (tTd(40, 1))
        extern bool readqf();
 
        if (tTd(40, 1))
@@ -794,19 +844,19 @@ dowork(id, forkflag, requeueflag, e)
 
        if (forkflag)
        {
 
        if (forkflag)
        {
-               i = fork();
-               if (i < 0)
+               pid = fork();
+               if (pid < 0)
                {
                        syserr("dowork: cannot fork");
                {
                        syserr("dowork: cannot fork");
-                       return;
+                       return 0;
                }
        }
        else
        {
                }
        }
        else
        {
-               i = 0;
+               pid = 0;
        }
 
        }
 
-       if (i == 0)
+       if (pid == 0)
        {
                /*
                **  CHILD
        {
                /*
                **  CHILD
@@ -819,9 +869,15 @@ dowork(id, forkflag, requeueflag, e)
                /* set basic modes, etc. */
                (void) alarm(0);
                clearenvelope(e, FALSE);
                /* set basic modes, etc. */
                (void) alarm(0);
                clearenvelope(e, FALSE);
-               e->e_flags |= EF_QUEUERUN;
+               e->e_flags |= EF_QUEUERUN|EF_GLOBALERRS;
                e->e_errormode = EM_MAIL;
                e->e_id = id;
                e->e_errormode = EM_MAIL;
                e->e_id = id;
+               GrabTo = UseErrorsTo = FALSE;
+               if (forkflag)
+               {
+                       disconnect(1, e);
+                       OpMode = MD_DELIVER;
+               }
 # ifdef LOG
                if (LogLevel > 76)
                        syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id,
 # ifdef LOG
                if (LogLevel > 76)
                        syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id,
@@ -832,7 +888,7 @@ dowork(id, forkflag, requeueflag, e)
                e->e_header = NULL;
 
                /* read the queue control file -- return if locked */
                e->e_header = NULL;
 
                /* read the queue control file -- return if locked */
-               if (!readqf(e))
+               if (!readqf(e, !requeueflag))
                {
                        if (tTd(40, 4))
                                printf("readqf(%s) failed\n", e->e_id);
                {
                        if (tTd(40, 4))
                                printf("readqf(%s) failed\n", e->e_id);
@@ -857,21 +913,16 @@ dowork(id, forkflag, requeueflag, e)
                else
                        dropenvelope(e);
        }
                else
                        dropenvelope(e);
        }
-       else if (!requeueflag)
-       {
-               /*
-               **  Parent -- pick up results.
-               */
-
-               errno = 0;
-               (void) waitfor(i);
-       }
+       e->e_id = NULL;
+       return pid;
 }
 \f/*
 **  READQF -- read queue file and set up environment.
 **
 **     Parameters:
 **             e -- the envelope of the job to run.
 }
 \f/*
 **  READQF -- read queue file and set up environment.
 **
 **     Parameters:
 **             e -- the envelope of the job to run.
+**             announcefile -- if set, announce the name of the queue
+**                     file in error messages.
 **
 **     Returns:
 **             TRUE if it successfully read the queue file.
 **
 **     Returns:
 **             TRUE if it successfully read the queue file.
@@ -882,8 +933,9 @@ dowork(id, forkflag, requeueflag, e)
 */
 
 bool
 */
 
 bool
-readqf(e)
+readqf(e, announcefile)
        register ENVELOPE *e;
        register ENVELOPE *e;
+       bool announcefile;
 {
        register FILE *qfp;
        ADDRESS *ctladdr;
 {
        register FILE *qfp;
        ADDRESS *ctladdr;
@@ -910,6 +962,21 @@ readqf(e)
                return FALSE;
        }
 
                return FALSE;
        }
 
+       if (!lockfile(fileno(qfp), qf, NULL, LOCK_EX|LOCK_NB))
+       {
+               /* being processed by another queuer */
+               if (tTd(40, 8))
+                       printf("readqf(%s): locked\n", qf);
+               if (Verbose)
+                       printf("%s: locked\n", e->e_id);
+# ifdef LOG
+               if (LogLevel > 19)
+                       syslog(LOG_DEBUG, "%s: locked", e->e_id);
+# endif /* LOG */
+               (void) fclose(qfp);
+               return FALSE;
+       }
+
        /*
        **  Check the queue file for plausibility to avoid attacks.
        */
        /*
        **  Check the queue file for plausibility to avoid attacks.
        */
@@ -924,7 +991,7 @@ readqf(e)
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if (st.st_uid != geteuid() || (st.st_mode & 07777) != FileMode)
+       if (st.st_uid != geteuid())
        {
 # ifdef LOG
                if (LogLevel > 0)
        {
 # ifdef LOG
                if (LogLevel > 0)
@@ -935,41 +1002,41 @@ readqf(e)
 # endif /* LOG */
                if (tTd(40, 8))
                        printf("readqf(%s): bogus file\n", qf);
 # endif /* LOG */
                if (tTd(40, 8))
                        printf("readqf(%s): bogus file\n", qf);
+               rename(qf, queuename(e, 'Q'));
                fclose(qfp);
                return FALSE;
        }
 
                fclose(qfp);
                return FALSE;
        }
 
-       if (!lockfile(fileno(qfp), qf, LOCK_EX|LOCK_NB))
+       if (st.st_size == 0)
        {
        {
-               /* being processed by another queuer */
-               if (tTd(40, 8))
-                       printf("readqf(%s): locked\n", qf);
-               if (Verbose)
-                       printf("%s: locked\n", e->e_id);
-# ifdef LOG
-               if (LogLevel > 19)
-                       syslog(LOG_DEBUG, "%s: locked", e->e_id);
-# endif /* LOG */
-               (void) fclose(qfp);
+               /* must be a bogus file -- just remove it */
+               (void) unlink(qf);
+               fclose(qfp);
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if (st.st_size == 0)
+       if (st.st_nlink == 0)
        {
        {
-               /* must be a bogus file -- just remove it */
-               (void) unlink(qf);
+               /*
+               **  Race condition -- we got a file just as it was being
+               **  unlinked.  Just assume it is zero length.
+               */
+
                fclose(qfp);
                return FALSE;
        }
 
                fclose(qfp);
                return FALSE;
        }
 
-       /* save this lock */
+       /* good file -- save this lock */
        e->e_lockfp = qfp;
 
        /* do basic system initialization */
        initsys(e);
 
        e->e_lockfp = qfp;
 
        /* do basic system initialization */
        initsys(e);
 
-       FileName = qf;
+       if (announcefile)
+               FileName = qf;
        LineNumber = 0;
        LineNumber = 0;
+       e->e_flags |= EF_GLOBALERRS;
+       OpMode = MD_DELIVER;
        if (Verbose)
                printf("\nRunning %s\n", e->e_id);
        ctladdr = NULL;
        if (Verbose)
                printf("\nRunning %s\n", e->e_id);
        ctladdr = NULL;
@@ -999,7 +1066,7 @@ readqf(e)
                        break;
 
                  case 'M':             /* message */
                        break;
 
                  case 'M':             /* message */
-                       e->e_message = newstr(&bp[1]);
+                       /* ignore this; we want a new message next time */
                        break;
 
                  case 'S':             /* sender */
                        break;
 
                  case 'S':             /* sender */
@@ -1056,7 +1123,9 @@ readqf(e)
                  default:
                        syserr("readqf: bad line \"%s\"", e->e_id,
                                LineNumber, bp);
                  default:
                        syserr("readqf: bad line \"%s\"", e->e_id,
                                LineNumber, bp);
-                       break;
+                       fclose(qfp);
+                       rename(qf, queuename(e, 'Q'));
+                       return FALSE;
                }
 
                if (bp != buf)
                }
 
                if (bp != buf)
@@ -1101,12 +1170,12 @@ printqueue()
        **  Check for permission to print the queue
        */
 
        **  Check for permission to print the queue
        */
 
-       if (bitset(PRIV_RESTRMAILQ, PrivacyFlags) && getuid() != 0)
+       if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0)
        {
                struct stat st;
 # ifdef NGROUPS
                int n;
        {
                struct stat st;
 # ifdef NGROUPS
                int n;
-               int gidset[NGROUPS];
+               GIDSET_T gidset[NGROUPS];
 # endif
 
                if (stat(QueueDir, &st) < 0)
 # endif
 
                if (stat(QueueDir, &st) < 0)
@@ -1123,7 +1192,7 @@ printqueue()
                }
                if (n < 0)
 # else
                }
                if (n < 0)
 # else
-               if (getgid() != st.st_gid)
+               if (RealGid != st.st_gid)
 # endif
                {
                        usrerr("510 You are not permitted to see the queue");
 # endif
                {
                        usrerr("510 You are not permitted to see the queue");
@@ -1167,14 +1236,15 @@ printqueue()
                char message[MAXLINE];
                char bodytype[MAXNAME];
 
                char message[MAXLINE];
                char bodytype[MAXNAME];
 
+               printf("%8s", w->w_name + 2);
                f = fopen(w->w_name, "r");
                if (f == NULL)
                {
                f = fopen(w->w_name, "r");
                if (f == NULL)
                {
+                       printf(" (job completed)\n");
                        errno = 0;
                        continue;
                }
                        errno = 0;
                        continue;
                }
-               printf("%8s", w->w_name + 2);
-               if (!lockfile(fileno(f), w->w_name, LOCK_SH|LOCK_NB))
+               if (!lockfile(fileno(f), w->w_name, NULL, LOCK_SH|LOCK_NB))
                        printf("*");
                else if (shouldqueue(w->w_pri, w->w_ctime))
                        printf("X");
                        printf("*");
                else if (shouldqueue(w->w_pri, w->w_ctime))
                        printf("X");
@@ -1336,11 +1406,11 @@ queuename(e, type)
                        {
                                if (errno == EEXIST)
                                        continue;
                        {
                                if (errno == EEXIST)
                                        continue;
-                               syserr("queuename: Cannot create \"%s\" in \"%s\"",
-                                       qf, QueueDir);
+                               syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",
+                                       qf, QueueDir, geteuid());
                                exit(EX_UNAVAILABLE);
                        }
                                exit(EX_UNAVAILABLE);
                        }
-                       if (lockfile(i, qf, LOCK_EX|LOCK_NB))
+                       if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB))
                        {
                                e->e_lockfp = fdopen(i, "w");
                                break;
                        {
                                e->e_lockfp = fdopen(i, "w");
                                break;
@@ -1351,14 +1421,19 @@ queuename(e, type)
                }
                if (c1 >= '~' && c2 >= 'Z')
                {
                }
                if (c1 >= '~' && c2 >= 'Z')
                {
-                       syserr("queuename: Cannot create \"%s\" in \"%s\"",
-                               qf, QueueDir);
+                       syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",
+                               qf, QueueDir, geteuid());
                        exit(EX_OSERR);
                }
                e->e_id = newstr(&qf[2]);
                define('i', e->e_id, e);
                if (tTd(7, 1))
                        printf("queuename: assigned id %s, env=%x\n", e->e_id, e);
                        exit(EX_OSERR);
                }
                e->e_id = newstr(&qf[2]);
                define('i', e->e_id, e);
                if (tTd(7, 1))
                        printf("queuename: assigned id %s, env=%x\n", e->e_id, e);
+               if (tTd(7, 9))
+               {
+                       printf("  lockfd=");
+                       dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
+               }
 # ifdef LOG
                if (LogLevel > 93)
                        syslog(LOG_DEBUG, "%s: assigned id", e->e_id);
 # ifdef LOG
                if (LogLevel > 93)
                        syslog(LOG_DEBUG, "%s: assigned id", e->e_id);
@@ -1437,8 +1512,8 @@ setctluser(user)
        **  See if this clears our concept of controlling user.
        */
 
        **  See if this clears our concept of controlling user.
        */
 
-       if (user == NULL)
-               user = "";
+       if (user == NULL || *user == '\0')
+               return NULL;
 
        /*
        **  Set up addr fields for controlling user.
 
        /*
        **  Set up addr fields for controlling user.