Import a copy of Markus Schnalke's master's thesis: The Modern Mail Handler.
[mmh] / docs / historical / mh-6.8.5 / uip / rmf.c
1 /* rmf.c - remove a folder */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: rmf.c,v 2.7 1992/12/15 00:20:22 jromine Exp $";
4 #endif  /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/local.h"
8 #include <stdio.h>
9 #ifdef LOCALE
10 #include        <locale.h>
11 #endif
12
13 /* \f */
14
15 static struct swit switches[] = {
16 #define INTRSW  0
17     "interactive", 0,
18 #define NINTRSW 1
19     "nointeractive", 0,
20
21 #define HELPSW  2
22     "help", 4,
23
24     NULL, 0
25 };
26
27 static  int     rmf();
28 static          rma();
29 /* \f */
30
31 /* ARGSUSED */
32
33 main (argc, argv)
34 int argc;
35 char *argv[];
36 {
37     int     defolder = 0,
38             interactive = -1;
39     char   *cp,
40            *folder = NULL,
41             newfolder[BUFSIZ],
42             buf[100],
43           **ap,
44           **argp,
45            *arguments[MAXARGS];
46
47 #ifdef LOCALE
48         setlocale(LC_ALL, "");
49 #endif
50     invo_name = r1bindex (argv[0], '/');
51     if ((cp = m_find (invo_name)) != NULL) {
52         ap = brkstring (cp = getcpy (cp), " ", "\n");
53         ap = copyip (ap, arguments);
54     }
55     else
56         ap = arguments;
57     (void) copyip (argv + 1, ap);
58     argp = arguments;
59
60 /* \f */
61
62     while (cp = *argp++) {
63         if (*cp == '-')
64             switch (smatch (++cp, switches)) {
65                 case AMBIGSW: 
66                     ambigsw (cp, switches);
67                     done (1);
68                 case UNKWNSW: 
69                     adios (NULLCP, "-%s unknown", cp);
70                 case HELPSW: 
71                     (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
72                     help (buf, switches);
73                     done (1);
74
75                 case INTRSW: 
76                     interactive = 1;
77                     continue;
78                 case NINTRSW: 
79                     interactive = 0;
80                     continue;
81             }
82         if (*cp == '+' || *cp == '@') {
83             if (folder)
84                 adios (NULLCP, "only one folder at a time!");
85             else
86                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
87         }
88         else
89             adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
90     }
91
92 /* \f */
93
94     if (!m_find ("path"))
95         free (path ("./", TFOLDER));
96     if (!folder) {
97         folder = m_getfolder ();
98         defolder++;
99     }
100     if (strcmp (m_mailpath (folder), pwd ()) == 0)
101         adios (NULLCP, "sorry, you can't remove the current working directory");
102
103     if (interactive == -1)
104         interactive = defolder;
105
106     if (index (folder, '/') && (*folder != '/') && (*folder != '.')) {
107         for (cp = copy (folder, newfolder); cp > newfolder && *cp != '/'; cp--)
108             continue;
109         if (cp > newfolder)
110             *cp = '\0';
111         else
112             (void) strcpy (newfolder, (cp = m_find (inbox)) ? cp : defalt);
113     }
114     else
115         (void) strcpy (newfolder, (cp = m_find (inbox)) ? cp : defalt);
116
117     if (interactive) {
118         cp = concat ("Remove folder \"", folder, "\"? ", NULLCP);
119         if (!getanswer (cp))
120             done (0);
121         free (cp);
122     }
123
124     if (rmf (folder) == OK && strcmp (m_find (pfolder), newfolder)) {
125         printf ("[+%s now current]\n", newfolder);
126         m_replace (pfolder, newfolder);
127     }
128     m_update ();
129
130     done (0);
131 }
132
133 /* \f */
134
135 static int  rmf (folder)
136 register char *folder;
137 {
138     int     i,
139             j,
140             others;
141     register char  *maildir;
142     char    cur[BUFSIZ];
143 #ifdef SYS5DIR
144     register struct dirent *dp;
145 #else   /*  SYS5DIR */
146     register struct direct *dp;
147 #endif  /* SYS5DIR */
148     register    DIR * dd;
149
150 #ifdef  COMPAT
151     (void) m_delete (concat (current, "-", m_mailpath (folder), NULLCP));
152 #endif  /* COMPAT */
153     switch (i = chdir (maildir = m_maildir (folder))) {
154         case OK: 
155             if (access (".", 2) != NOTOK && access ("..", 2) != NOTOK)
156                 break;          /* fall otherwise */
157
158         case NOTOK: 
159             (void) sprintf (cur, "atr-%s-%s", current, m_mailpath (folder));
160             if (!m_delete (cur)) {
161                 printf ("[+%s de-referenced]\n", folder);
162                 return OK;
163             }
164             advise (NULLCP, "you have no profile entry for the %s folder +%s",
165                     i == NOTOK ? "unreadable" : "read-only", folder);
166             return NOTOK;
167     }
168
169     if ((dd = opendir (".")) == NULL)
170         adios (NULLCP, "unable to read folder +%s", folder);
171     others = 0;
172
173     j = strlen (SBACKUP);
174     while (dp = readdir (dd)) {
175         switch (dp -> d_name[0]) {
176             case '.': 
177                 if (strcmp (dp -> d_name, ".") == 0
178                         || strcmp (dp -> d_name, "..") == 0)
179                     continue;   /* else fall */
180
181             case ',': 
182 #ifdef  MHE
183             case '+': 
184 #endif  /* MHE */
185 #ifdef  UCI
186             case '_': 
187             case '#': 
188 #endif  /* UCI */
189                 break;
190
191             default: 
192                 if (m_atoi (dp -> d_name))
193                     break;
194 #ifdef  COMPAT
195                 if (strcmp (dp -> d_name, current) == 0)
196                     break;
197 #endif  /* COMPAT */
198                 if (strcmp (dp -> d_name, LINK) == 0
199                         || strncmp (dp -> d_name, SBACKUP, j) == 0)
200                     break;
201
202                 admonish (NULLCP, "file \"%s/%s\" not deleted",
203                         folder, dp -> d_name);
204                 others++;
205                 continue;
206         }
207         if (unlink (dp -> d_name) == NOTOK) {
208             admonish (dp -> d_name, "unable to unlink %s:", folder);
209             others++;
210         }
211     }
212
213     closedir (dd);
214
215     rma (folder);
216
217     (void) chdir ("..");
218     if (others == 0 && remdir (maildir))
219         return OK;
220
221     advise (NULLCP, "folder +%s not removed", folder);
222     return NOTOK;
223 }
224
225 /* \f */
226
227 static  rma (folder)
228 register char   *folder;
229 {
230     register int    alen,
231                     j,
232                     plen;
233     register char  *cp;
234     register struct node   *np,
235                            *pp;
236
237     alen = strlen ("atr-");
238     plen = strlen (cp = m_mailpath (folder)) + 1;
239
240     m_getdefs ();
241     for (np = m_defs, pp = NULL; np; np = np -> n_next)
242         if (ssequal ("atr-", np -> n_name)
243                 && (j = strlen (np -> n_name) - plen) > alen
244                 && *(np -> n_name + j) == '-'
245                 && strcmp (cp, np -> n_name + j + 1) == 0) {
246             if (!np -> n_context)
247                 admonish (NULLCP, "bug: m_delete(key=\"%s\")", np -> n_name);
248             if (pp) {
249                 pp -> n_next = np -> n_next;
250                 np = pp;
251             }
252             else
253                 m_defs = np -> n_next;
254             ctxflags |= CTXMOD;
255         }
256         else
257             pp = np;
258 }