Back to index

courier  0.68.2
mailq.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2007 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "courier.h"
00007 #include      "localstatedir.h"
00008 #include      "mydirent.h"
00009 #include      "comctlfile.h"
00010 #include      "comstrinode.h"
00011 #include      "comcargs.h"
00012 #include      "maxlongsize.h"
00013 #include      <sys/types.h>
00014 #if    HAVE_SYS_STAT_H
00015 #include      <sys/stat.h>
00016 #endif
00017 #if    HAVE_UNISTD_H
00018 #include      <unistd.h>
00019 #endif
00020 #include      <time.h>
00021 #include      <pwd.h>
00022 #include      <stdlib.h>
00023 #include      <string.h>
00024 
00025 
00026 static const char *sortflag=0;
00027 static const char *batchflag=0;
00028 
00029 static struct courier_args arginfo[]={
00030        {"sort", &sortflag},
00031        {"batch",&batchflag},
00032        {0, 0}};
00033 
00034 /*
00035 
00036 Size  Qid                          Date
00037 User   Sender
00038 Status Recipient
00039 
00040 */
00041 
00042 static void showqline(const char *a, const char *b, const char *c)
00043 {
00044        if(batchflag) {
00045               if(c)
00046                      printf("%s;%s;%s;", a, b, c);
00047               else
00048                      printf("%s;%s;", a, b);
00049        }
00050        else {
00051               if (c)
00052                      printf("%16s %-*s %s\n", a,
00053                             (int)(sizeof(ino_t)+sizeof(time_t)*2+sizeof(pid_t))*2+3,
00054                             b, c);
00055               else
00056                      printf("%-16s %s\n", a, b);
00057        }
00058 }
00059 
00060 static void showq(struct ctlfile *ctf, struct stat *stat_buf)
00061 {
00062 char size[MAXLONGSIZE+10], size2[17];
00063 char buf[sizeof("Mar 12 xx:xx")+40];
00064 struct tm *tmptr;
00065 int    n;
00066 struct passwd *pw;
00067 const char *fld1;
00068 const char *qid="";
00069 
00070        n=ctlfile_searchfirst(ctf, COMCTLFILE_MSGID);
00071        if (n >= 0)   qid=ctf->lines[n]+1;
00072 
00073        if (stat_buf->st_size < 1024)
00074               sprintf(size, "%d", (int)stat_buf->st_size);
00075        else if (stat_buf->st_size < 1024 * 1024)
00076               sprintf(size, "%d.%dK", (int)stat_buf->st_size / 1024,
00077                      ((int)stat_buf->st_size % 1024) * 10 / 1024);
00078        else
00079               sprintf(size, "%ld.%02ldM",
00080                      (int)stat_buf->st_size / (1024*1024L),
00081                      ((long)stat_buf->st_size % (1024*1024L)) * 100
00082                             / (1024 * 1024L));
00083        sprintf(size2, "%-*.*s", (int)sizeof(size2)-1, (int)sizeof(size2)-1,
00084               size);
00085 
00086        tmptr=localtime(&stat_buf->st_mtime);
00087        strftime(buf, sizeof(buf)-1, "%b %d %H:%M", tmptr);
00088 
00089        showqline(size2, qid, buf);
00090 
00091        pw=getpwuid(stat_buf->st_uid);
00092        fld1=pw ? pw->pw_name:"";
00093        n=ctlfile_searchfirst(ctf, COMCTLFILE_SENDER);
00094        qid= n >= 0 ? ctf->lines[n]+1:"";
00095        showqline(fld1, qid, 0);
00096 
00097        for (n=0; (unsigned)n < ctf->nreceipients; n++)
00098        {
00099        unsigned i;
00100        const char *sf="";
00101 
00102               for (i=0; ctf->lines[i]; i++)
00103               {
00104                      switch (ctf->lines[i][0])   {
00105                      case COMCTLFILE_DELSUCCESS:
00106                             if (atoi(ctf->lines[i]+1) == n)
00107                             {
00108                                    sf="done";
00109                                    break;
00110                             }
00111                             continue;
00112                      case COMCTLFILE_DELFAIL:
00113                             if (atoi(ctf->lines[i]+1) == n)
00114                             {
00115                                    sf="fail";
00116                                    break;
00117                             }
00118                             continue;
00119                      default:
00120                             continue;
00121                      }
00122                      break;
00123               }
00124 
00125               showqline(sf, ctf->receipients[n], 0);
00126        }
00127        printf("\n");
00128 }
00129 
00130 static struct sortlist {
00131        struct sortlist *next;
00132        char *filename;
00133        time_t timestamp;
00134        } *sortlistp=0;
00135 static unsigned sortcnt;
00136 
00137 static int sortcmp(struct sortlist **a, struct sortlist **b)
00138 {
00139        return ( (*a)->timestamp < (*b)->timestamp ? -1:
00140               (*a)->timestamp > (*b)->timestamp ? 1:0);
00141 }
00142 
00143 int main(int argc, char **argv)
00144 {
00145 DIR    *topdirp, *dirp;
00146 struct dirent *topdire, *dire;
00147 struct ctlfile ctf;
00148 struct stat stat_buf;
00149 unsigned qcount=0;
00150 uid_t  u=getuid();
00151 
00152        (void)cargs(argc, argv, arginfo);
00153        if (chdir(courierdir()) || chdir(MSGSDIR))
00154        {
00155               perror("chdir");
00156               exit(1);
00157        }
00158 
00159        if ((topdirp=opendir(".")) == 0)
00160        {
00161               perror("topdirp");
00162               exit(1);
00163        }
00164        
00165        if(!batchflag)
00166        {
00167               showqline("Size            ", "Queue ID", "Date");
00168               showqline("User", "From", 0);
00169               showqline("Status", "Recipient", 0);
00170               showqline("----------------",
00171                      "---------------------------------------------------------", 0);
00172        }
00173 
00174        while ((topdire=readdir(topdirp)) != 0)
00175        {
00176        const char *p=topdire->d_name;
00177 
00178               while (*p)
00179               {
00180                      if (*p < '0' || *p > '9')   break;
00181                      ++p;
00182               }
00183               if (*p)       continue;
00184 
00185               if ((dirp=opendir(topdire->d_name)) == 0) continue;
00186               while ((dire=readdir(dirp)) != 0)
00187               {
00188               char   *name;
00189 
00190                      p=dire->d_name;
00191                      if (*p != 'C')       continue;
00192                      if ((name=malloc(strlen(topdire->d_name)
00193                                    +strlen(p)+2)) == 0)
00194                      {
00195                             perror("malloc");
00196                             exit(1);
00197                      }
00198                      strcat(strcat(strcpy(name, topdire->d_name), "/"), p);
00199 
00200                      if (sortflag)
00201                      {
00202                      struct sortlist *sortp;
00203 
00204                             *strchr(name, 'C')='D';
00205                             if (stat(name, &stat_buf) || (u &&
00206                                    stat_buf.st_uid != u))
00207                             {
00208                                    free(name);
00209                                    continue;
00210                             }
00211                             if ( (sortp=(struct sortlist *)
00212                                    malloc(sizeof(struct sortlist))) == 0)
00213                             {
00214                                    perror("malloc");
00215                                    exit(1);
00216                             }
00217                             sortp->next=sortlistp;
00218                             sortlistp=sortp;
00219                             sortp->filename=name;
00220                             sortp->timestamp=stat_buf.st_mtime;
00221                             ++sortcnt;
00222                             continue;
00223                      }
00224 
00225                      if (ctlfile_openfn(name, &ctf, 1, 0) == 0)
00226                      {
00227                             *strchr(name, 'C')='D';
00228 
00229                             if (stat(name, &stat_buf) == 0 && (u == 0 ||
00230                                    stat_buf.st_uid == u))
00231                             {
00232                                    ctf.starttime=stat_buf.st_mtime;
00233                                    showq(&ctf, &stat_buf);
00234                                    ++qcount;
00235                             }
00236                             ctlfile_close(&ctf);
00237                      }
00238                      free(name);
00239               }
00240               closedir(dirp);
00241        }
00242        closedir(topdirp);
00243 
00244        if (sortflag && sortcnt)
00245        {
00246        struct sortlist **sorta=(struct sortlist **)malloc(
00247                      sortcnt*sizeof(struct sortlist *));
00248        struct sortlist *sortp;
00249        unsigned i;
00250 
00251               if (!sorta)
00252               {
00253                      perror("malloc");
00254                      exit(1);
00255               }
00256               for (i=0, sortp=sortlistp; sortp; sortp=sortp->next)
00257                      sorta[i++]=sortp;
00258               qsort(sorta, sortcnt, sizeof(*sorta),
00259                      ( int (*)(const void *, const void *))sortcmp);
00260 
00261               for (i=0; i<sortcnt; i++)
00262               {
00263                      if (stat(sorta[i]->filename, &stat_buf)) continue;
00264                      *strchr(sorta[i]->filename, 'D')='C';
00265                      if (ctlfile_openfn(sorta[i]->filename, &ctf, 1, 0))
00266                             continue;
00267                      ctf.starttime=stat_buf.st_mtime;
00268                      showq(&ctf, &stat_buf);
00269                      ctlfile_close(&ctf);
00270                      ++qcount;
00271               }
00272        }
00273 
00274        if(batchflag)
00275               printf("messages: %d\n",qcount);
00276        else
00277               printf("%4d messages.\n", qcount);
00278        return (0);
00279 }