Back to index

courier  0.68.2
commsgcancel.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 1999 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "courier_lib_config.h"
00007 #include      "courier.h"
00008 #include      "comqueuename.h"
00009 #include      "comctlfile.h"
00010 #include      "comparseqid.h"
00011 #include      "comctlfile.h"
00012 #include      "commsgcancel.h"
00013 #include      <sys/types.h>
00014 #include      <sys/uio.h>
00015 #include      <string.h>
00016 #include      <signal.h>
00017 #include      <stdlib.h>
00018 #if    HAVE_UNISTD_H
00019 #include      <unistd.h>
00020 #endif
00021 #if    HAVE_FCNTL_H
00022 #include      <fcntl.h>
00023 #endif
00024 #if    HAVE_SYS_IOCTL_H
00025 #include      <sys/ioctl.h>
00026 #endif
00027 #if    HAVE_SYS_STAT_H
00028 #include      <sys/stat.h>
00029 #endif
00030 
00031 int msgcancel(const char *qid, const char **reason, int nreason,
00032        int chkuid)
00033 {
00034 ino_t  n;
00035 struct ctlfile ctf;
00036 struct stat   stat_buf;
00037 uid_t  u=getuid();
00038 int    c, d;
00039 struct iovec *iova;
00040 static const char default_cancel_msg[]="Message cancelled.";
00041 static const char *default_cancel_msgp[1]= { default_cancel_msg };
00042 
00043 static const char x=COMCTLFILE_CANCEL_MSG;
00044 char   *s;
00045 
00046        if (comparseqid(qid, &n))   return (-1);
00047         if (ctlfile_openi(n, &ctf, 0))    return (-1);
00048        if (fstat(ctf.fd, &stat_buf) || (chkuid && u && u != stat_buf.st_uid) ||
00049               ctf.cancelled)
00050        {
00051               ctlfile_close(&ctf);
00052               return (-1);
00053        }
00054        c=ctlfile_searchfirst(&ctf, COMCTLFILE_MSGID);
00055        if (c < 0 || strcmp(ctf.lines[c]+1, qid))
00056        {
00057               ctlfile_close(&ctf);
00058               return (-1);
00059        }
00060 
00061        if ((iova=(struct iovec *)malloc(sizeof(struct iovec) * 3 *
00062               (nreason == 0 ? 1:nreason))) == 0)
00063        {
00064               perror("enomem");
00065               exit(1);
00066        }
00067 
00068        if (nreason == 0)
00069        {
00070               reason=default_cancel_msgp;
00071               nreason=1;
00072        }
00073 
00074        c=0;
00075        while (nreason)
00076        {
00077               iova[c].iov_base=(caddr_t)&x;
00078               iova[c].iov_len=1;
00079               c++;
00080               iova[c].iov_base=(caddr_t) *reason;
00081               iova[c].iov_len=strlen( *reason );
00082               c++;
00083               iova[c].iov_base=(caddr_t)"\n";
00084               iova[c].iov_len=1;
00085               c++;
00086               ++reason;
00087               --nreason;
00088        }
00089 
00090        s=malloc(sizeof(TRIGGER_FLUSHMSG)+strlen(qid)+3);
00091        if (!s)
00092        {
00093               perror("malloc");
00094               exit(1);
00095        }
00096        strcat(strcat(strcpy(s, TRIGGER_FLUSHMSG " "), qid), "\n");
00097 
00098        d=writev(ctf.fd, iova, c);
00099        ctlfile_close(&ctf);
00100        while (c)
00101        {
00102               --c;
00103               if (iova[c].iov_len > d)
00104               {
00105                      perror("writev");
00106                      free(iova);
00107                      free(s);
00108                      return (0);
00109               }
00110               d -= iova[c].iov_len;
00111        }
00112        free(iova);
00113        trigger(s);
00114        free(s);
00115        return (0);
00116 }