summaryrefslogtreecommitdiffstats
path: root/maildir/maildirmake.c
diff options
context:
space:
mode:
Diffstat (limited to 'maildir/maildirmake.c')
-rw-r--r--maildir/maildirmake.c358
1 files changed, 358 insertions, 0 deletions
diff --git a/maildir/maildirmake.c b/maildir/maildirmake.c
new file mode 100644
index 0000000..001032c
--- /dev/null
+++ b/maildir/maildirmake.c
@@ -0,0 +1,358 @@
+/*
+** Copyright 1998 - 2006Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+
+#include "maildircreate.h"
+#include "maildirmisc.h"
+#include "maildirsharedrc.h"
+#include "maildirquota.h"
+#include "unicode/unicode.h"
+
+static void usage()
+{
+ printf("Usage: maildirmake [ options ] maildir\n");
+ exit(1);
+}
+
+extern FILE *maildir_shared_fopen(const char *, const char *);
+extern void maildir_shared_fparse(char *, char **, char **);
+
+static void add(const char *dir, const char *name)
+{
+char *c=malloc(strlen(name)+1);
+char *s;
+FILE *fp;
+char buf[BUFSIZ];
+char *ptr, *dirp;
+
+ if (!c)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ strcpy(c, name);
+
+ if ((s=strchr(c, '=')) == 0)
+ usage();
+ *s++=0;
+ if (*s != '/')
+ usage();
+ if (access(s, R_OK))
+ {
+ perror(s);
+ exit(1);
+ }
+ if (strchr(c, '.') || strchr(c, '/'))
+ {
+ fprintf(stderr, "%s: invalid name\n", c);
+ exit(1);
+ }
+
+ if (chdir(dir))
+ {
+ perror(dir);
+ exit(1);
+ }
+
+ if ((fp=fopen(MAILDIRSHAREDRC, "r")) != 0)
+ {
+ while ((ptr=fgets(buf, sizeof(buf), fp)) != 0)
+ {
+ char *namep;
+
+ maildir_shared_fparse(buf, &namep, &dirp);
+ if (!namep) continue;
+ if (strcmp(namep, c) == 0)
+ {
+ fclose(fp);
+ fprintf(stderr,
+ "%s: already defined as a sharable maildir in %s.\n",
+ namep, MAILDIRSHAREDRC);
+ exit(2);
+ }
+ }
+ fclose(fp);
+ }
+
+ if ((fp=maildir_shared_fopen(".", "a+")) == 0)
+ {
+ perror(dir);
+ exit(1);
+ }
+
+ if (fseek(fp, 0L, SEEK_SET) < 0)
+ {
+ perror(dir);
+ exit(1);
+ }
+
+ while ((ptr=fgets(buf, sizeof(buf), fp)) != 0)
+ {
+ char *namep;
+
+ maildir_shared_fparse(buf, &namep, &dirp);
+ if (!namep) continue;
+ if (strcmp(namep, c) == 0)
+ {
+ fclose(fp);
+ fprintf(stderr, "%s: already defined as a sharable maildir.\n",
+ namep);
+ exit(2);
+ }
+ }
+ fprintf(fp, "%s\t%s\n", c, s);
+ if (fflush(fp) || ferror(fp) || fclose(fp))
+ {
+ perror("dir");
+ exit(1);
+ }
+ exit(0);
+}
+
+static void del(const char *dir, const char *n)
+{
+FILE *fp;
+char buf[BUFSIZ];
+char buf2[BUFSIZ];
+
+FILE *fp2;
+int found;
+ struct maildir_tmpcreate_info createInfo;
+
+ if (chdir(dir))
+ {
+ perror(dir);
+ exit(1);
+ }
+ if ((fp=maildir_shared_fopen(".", "r")) == 0)
+ {
+ perror(dir);
+ exit(1);
+ }
+
+ maildir_tmpcreate_init(&createInfo);
+
+ createInfo.uniq="shared";
+ createInfo.msgsize=0;
+ createInfo.doordie=1;
+
+ if ((fp2=maildir_tmpcreate_fp(&createInfo)) == NULL)
+ {
+ perror(dir);
+ exit(1);
+ }
+
+ found=0;
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ char *name, *dirp;
+
+ strcpy(buf2, buf);
+ maildir_shared_fparse(buf2, &name, &dirp);
+ if (name && strcmp(name, n) == 0)
+ {
+ found=1;
+ continue;
+ }
+ fprintf(fp2, "%s", buf);
+ }
+ fclose(fp);
+ if (fflush(fp2) || ferror(fp2) || fclose(fp2)
+ || rename(createInfo.tmpname, "shared-maildirs"))
+ {
+ perror(createInfo.tmpname);
+ unlink(createInfo.tmpname);
+ exit(1);
+ }
+ maildir_tmpcreate_free(&createInfo);
+ if (!found)
+ {
+ fprintf(stderr, "%s: not found.\n", n);
+ exit(1);
+ }
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+const char *maildir, *folder=0;
+char *p;
+int argn;
+int perm=0700;
+int musthavefolder=0;
+int subdirperm;
+char *addshared=0, *delshared=0;
+const char *quota=0;
+char *tmp=0;
+
+ for (argn=1; argn<argc; argn++)
+ {
+ if (argv[argn][0] != '-') break;
+ if (strcmp(argv[argn], "-") == 0) break;
+ if (strncmp(argv[argn], "-f", 2) == 0)
+ {
+ folder=argv[argn]+2;
+ if (*folder == 0 && argn+1 < argc)
+ folder=argv[++argn];
+ continue;
+ }
+ if (strncmp(argv[argn], "-F", 2) == 0)
+ {
+ int converr;
+
+ const char *p=argv[argn]+2;
+
+ if (*p == 0 && argn+1 < argc)
+ p=argv[++argn];
+
+ folder=libmail_u_convert_tobuf(p,
+ unicode_default_chset(),
+ unicode_x_imap_modutf7,
+ &converr);
+
+ if (converr || !folder)
+ {
+ fprintf(stderr, "Cannot convert %s to maildir encoding\n",
+ p);
+ exit(1);
+ }
+ continue;
+ }
+ if (strcmp(argv[argn], "-S") == 0)
+ {
+ perm=0755;
+ continue;
+ }
+
+ if (strncmp(argv[argn], "-s", 2) == 0)
+ {
+ const char *p=argv[argn]+2;
+
+ if (*p == 0 && argn+1 < argc)
+ p=argv[++argn];
+
+ perm=0755;
+ for (; *p; ++p)
+ {
+ if (isspace((int)(unsigned char)*p) ||
+ *p == ',')
+ continue;
+ if (*p == 'r')
+ perm=0755;
+ else if (*p == 'w')
+ perm=0777 | S_ISVTX;
+ else if (*p == 'g')
+ perm &= ~0007;
+
+ while (*p && !isspace((int)(unsigned char)*p)
+ && *p != ',')
+ ++p;
+ if (!*p) break;
+ }
+ musthavefolder=1;
+ continue;
+ }
+
+ if (strncmp(argv[argn], "-q", 2) == 0)
+ {
+ const char *p=argv[argn]+2;
+
+ if (*p == 0 && argn+1 < argc)
+ p=argv[++argn];
+
+ quota=p;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "--add") == 0 && argc-argn > 1)
+ {
+ addshared=argv[++argn];
+ continue;
+ }
+
+ if (strcmp(argv[argn], "--del") == 0 && argc-argn > 1)
+ {
+ delshared=argv[++argn];
+ continue;
+ }
+
+ usage();
+ }
+
+ if (argn == argc) usage();
+ maildir=argv[argn];
+
+ if (addshared)
+ {
+ add(maildir, addshared);
+ exit (0);
+ }
+
+ if (delshared)
+ {
+ del(maildir, delshared);
+ exit (0);
+ }
+
+ if (folder && *folder == '.')
+ {
+ printf("Invalid folder name: %s\n", folder);
+ exit(1);
+ }
+
+ if (folder)
+ {
+ if ((p=(char *)malloc(strlen(maildir)+strlen(folder)+4)) == 0)
+ {
+ perror("maildirmake malloc");
+ exit(1);
+ }
+ strcat(strcat(strcpy(p, maildir), "/."), folder);
+ maildir=p;
+ }
+ else if (musthavefolder)
+ usage();
+
+ if (quota)
+ {
+ maildir_quota_set(maildir, quota);
+ exit(0);
+ }
+ subdirperm=perm;
+ if (!folder) subdirperm=0700;
+ umask(0);
+ if (maildir_make(maildir, perm & ~0022, subdirperm, folder ? 1:0) < 0)
+ {
+ tmp=(char *)malloc(strlen(maildir)+14);
+ if (!tmp) {
+ perror("maildirmake malloc");
+ exit(1);
+ }
+ snprintf(tmp, 14+strlen(maildir), "maildirmake: %s", maildir);
+ perror(tmp);
+ exit(1);
+ }
+ exit(0);
+ return (0);
+}