Back to index

courier  0.68.2
maildirmake.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2006Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 
00007 #if    HAVE_CONFIG_H
00008 #include      "config.h"
00009 #endif
00010 #include      <stdio.h>
00011 #include      <string.h>
00012 #include      <stdlib.h>
00013 #if    HAVE_FCNTL_H
00014 #include      <fcntl.h>
00015 #endif
00016 #if    HAVE_UNISTD_H
00017 #include      <unistd.h>
00018 #endif
00019 #include      <sys/types.h>
00020 #if    HAVE_SYS_STAT_H
00021 #include      <sys/stat.h>
00022 #endif
00023 #include      <ctype.h>
00024 #include      <errno.h>
00025 
00026 #include      "maildircreate.h"
00027 #include      "maildirmisc.h"
00028 #include      "maildirsharedrc.h"
00029 #include      "maildirquota.h"
00030 
00031 static void usage()
00032 {
00033        printf("Usage: maildirmake [ options ] maildir\n");
00034        exit(1);
00035 }
00036 
00037 extern FILE *maildir_shared_fopen(const char *, const char *);
00038 extern void maildir_shared_fparse(char *, char **, char **);
00039 
00040 static void add(const char *dir, const char *name)
00041 {
00042 char   *c=malloc(strlen(name)+1);
00043 char   *s;
00044 FILE   *fp;
00045 char   buf[BUFSIZ];
00046 char   *ptr, *dirp;
00047 
00048        if (!c)
00049        {
00050               perror("malloc");
00051               exit(1);
00052        }
00053        strcpy(c, name);
00054 
00055        if ((s=strchr(c, '=')) == 0)
00056               usage();
00057        *s++=0;
00058        if (*s != '/')
00059               usage();
00060        if (access(s, R_OK))
00061        {
00062               perror(s);
00063               exit(1);
00064        }
00065        if (strchr(c, '.') || strchr(c, '/'))
00066        {
00067               fprintf(stderr, "%s: invalid name\n", c);
00068               exit(1);
00069        }
00070 
00071        if (chdir(dir))
00072        {
00073               perror(dir);
00074               exit(1);
00075        }
00076 
00077        if ((fp=fopen(MAILDIRSHAREDRC, "r")) != 0)
00078        {
00079               while ((ptr=fgets(buf, sizeof(buf), fp)) != 0)
00080               {
00081               char   *namep;
00082 
00083                      maildir_shared_fparse(buf, &namep, &dirp);
00084                      if (!namep)   continue;
00085                      if (strcmp(namep, c) == 0)
00086                      {
00087                             fclose(fp);
00088                             fprintf(stderr,
00089               "%s: already defined as a sharable maildir in %s.\n",
00090                                    namep, MAILDIRSHAREDRC);
00091                             exit(2);
00092                      }
00093               }
00094               fclose(fp);
00095        }
00096 
00097        if ((fp=maildir_shared_fopen(".", "a+")) == 0)
00098        {
00099               perror(dir);
00100               exit(1);
00101        }
00102 
00103        if (fseek(fp, 0L, SEEK_SET) < 0)
00104        {
00105               perror(dir);
00106               exit(1);
00107        }
00108 
00109        while ((ptr=fgets(buf, sizeof(buf), fp)) != 0)
00110        {
00111        char   *namep;
00112 
00113               maildir_shared_fparse(buf, &namep, &dirp);
00114               if (!namep)   continue;
00115               if (strcmp(namep, c) == 0)
00116               {
00117                      fclose(fp);
00118                      fprintf(stderr, "%s: already defined as a sharable maildir.\n",
00119                             namep);
00120                      exit(2);
00121               }
00122        }
00123        fprintf(fp, "%s\t%s\n", c, s);
00124        if (fflush(fp) || ferror(fp) || fclose(fp))
00125        {
00126               perror("dir");
00127               exit(1);
00128        }
00129        exit(0);
00130 }
00131 
00132 static void del(const char *dir, const char *n)
00133 {
00134 FILE   *fp;
00135 char   buf[BUFSIZ];
00136 char   buf2[BUFSIZ];
00137 
00138 FILE   *fp2;
00139 int    found;
00140  struct maildir_tmpcreate_info createInfo;
00141 
00142        if (chdir(dir))
00143        {
00144               perror(dir);
00145               exit(1);
00146        }
00147        if ((fp=maildir_shared_fopen(".", "r")) == 0)
00148        {
00149               perror(dir);
00150               exit(1);
00151        }
00152 
00153        maildir_tmpcreate_init(&createInfo);
00154 
00155        createInfo.uniq="shared";
00156        createInfo.msgsize=0;
00157        createInfo.doordie=1;
00158 
00159        if ((fp2=maildir_tmpcreate_fp(&createInfo)) == NULL)
00160        {
00161               perror(dir);
00162               exit(1);
00163        }
00164 
00165        found=0;
00166        while (fgets(buf, sizeof(buf), fp))
00167        {
00168        char   *name, *dirp;
00169 
00170               strcpy(buf2, buf);
00171               maildir_shared_fparse(buf2, &name, &dirp);
00172               if (name && strcmp(name, n) == 0)
00173               {
00174                      found=1;
00175                      continue;
00176               }
00177               fprintf(fp2, "%s", buf);
00178        }
00179        fclose(fp);
00180        if (fflush(fp2) || ferror(fp2) || fclose(fp2)
00181            || rename(createInfo.tmpname, "shared-maildirs"))
00182        {
00183               perror(createInfo.tmpname);
00184               unlink(createInfo.tmpname);
00185               exit(1);
00186        }
00187        maildir_tmpcreate_free(&createInfo);
00188        if (!found)
00189        {
00190               fprintf(stderr, "%s: not found.\n", n);
00191               exit(1);
00192        }
00193        exit(0);
00194 }
00195 
00196 int main(int argc, char *argv[])
00197 {
00198 const char *maildir, *folder=0;
00199 char *p;
00200 int    argn;
00201 int    perm=0700;
00202 int    musthavefolder=0;
00203 int    subdirperm;
00204 char   *addshared=0, *delshared=0;
00205 const char *quota=0;
00206 char   *tmp=0;
00207 
00208        for (argn=1; argn<argc; argn++)
00209        {
00210               if (argv[argn][0] != '-')   break;
00211               if (strcmp(argv[argn], "-") == 0)  break;
00212               if (strncmp(argv[argn], "-f", 2) == 0)
00213               {
00214                      folder=argv[argn]+2;
00215                      if (*folder == 0 && argn+1 < argc)
00216                             folder=argv[++argn];
00217                      continue;
00218               }
00219               if (strcmp(argv[argn], "-S") == 0)
00220               {
00221                      perm=0755;
00222                      continue;
00223               }
00224 
00225               if (strncmp(argv[argn], "-s", 2) == 0)
00226               {
00227               const char *p=argv[argn]+2;
00228 
00229                      if (*p == 0 && argn+1 < argc)
00230                             p=argv[++argn];
00231 
00232                      perm=0755;
00233                      for (; *p; ++p)
00234                      {
00235                             if (isspace((int)(unsigned char)*p) ||
00236                                    *p == ',')
00237                                    continue;
00238                             if (*p == 'r')
00239                                    perm=0755;
00240                             else if (*p == 'w')
00241                                    perm=0777 | S_ISVTX;
00242                             else if (*p == 'g')
00243                                    perm &= ~0007;
00244 
00245                             while (*p && !isspace((int)(unsigned char)*p)
00246                                    && *p != ',')
00247                                    ++p;
00248                             if (!*p)      break;
00249                      }
00250                      musthavefolder=1;
00251                      continue;
00252               }
00253 
00254               if (strncmp(argv[argn], "-q", 2) == 0)
00255               {
00256                      const char *p=argv[argn]+2;
00257 
00258                      if (*p == 0 && argn+1 < argc)
00259                             p=argv[++argn];
00260 
00261                      quota=p;
00262                      continue;
00263               }
00264 
00265               if (strcmp(argv[argn], "--add") == 0 && argc-argn > 1)
00266               {
00267                      addshared=argv[++argn];
00268                      continue;
00269               }
00270 
00271               if (strcmp(argv[argn], "--del") == 0 && argc-argn > 1)
00272               {
00273                      delshared=argv[++argn];
00274                      continue;
00275               }
00276 
00277               usage();
00278        }
00279 
00280        if (argn == argc)    usage();
00281        maildir=argv[argn];
00282 
00283        if (addshared)
00284        {
00285               add(maildir, addshared);
00286               exit (0);
00287        }
00288 
00289        if (delshared)
00290        {
00291               del(maildir, delshared);
00292               exit (0);
00293        }
00294 
00295        if (folder && *folder == '.')
00296        {
00297               printf("Invalid folder name: %s\n", folder);
00298               exit(1);
00299        }
00300 
00301        if (folder)
00302        {
00303               if ((p=(char *)malloc(strlen(maildir)+strlen(folder)+4)) == 0)
00304               {
00305                      perror("maildirmake malloc");
00306                      exit(1);
00307               }
00308               strcat(strcat(strcpy(p, maildir), "/."), folder);
00309               maildir=p;
00310        }
00311        else   if (musthavefolder)
00312               usage();
00313 
00314        if (quota)
00315        {
00316               maildir_quota_set(maildir, quota);
00317               exit(0);
00318        }
00319        subdirperm=perm;
00320        if (!folder)  subdirperm=0700;
00321        umask(0);
00322        if (maildir_make(maildir, perm & ~0022, subdirperm, folder ? 1:0) < 0)
00323        {
00324               tmp=(char *)malloc(strlen(maildir)+14);
00325               if (!tmp) {
00326                      perror("maildirmake malloc");
00327                      exit(1);
00328               }
00329               snprintf(tmp, 14+strlen(maildir), "maildirmake: %s", maildir);
00330               perror(tmp);
00331               exit(1);
00332        }
00333        exit(0);
00334        return (0);
00335 }