source: trunk/third/nmh/uip/rmf.c @ 12455

Revision 12455, 5.3 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * rmf.c -- remove a folder
4 *
5 * $Id: rmf.c,v 1.1.1.1 1999-02-07 18:14:16 danw Exp $
6 */
7
8#include <h/mh.h>
9
10static struct swit switches[] = {
11#define INTRSW            0
12    { "interactive", 0 },
13#define NINTRSW           1
14    { "nointeractive", 0 },
15#define VERSIONSW         2
16    { "version", 0 },
17#define HELPSW            3
18    { "help", 4 },
19    { NULL, 0 }
20};
21
22/*
23 * static prototypes
24 */
25static int rmf(char *);
26static void rma (char *);
27
28
29int
30main (int argc, char **argv)
31{
32    int defolder = 0, interactive = -1;
33    char *cp, *folder = NULL, newfolder[BUFSIZ];
34    char buf[BUFSIZ], **argp, **arguments;
35
36#ifdef LOCALE
37    setlocale(LC_ALL, "");
38#endif
39    invo_name = r1bindex (argv[0], '/');
40
41    /* read user profile/context */
42    context_read();
43
44    arguments = getarguments (invo_name, argc, argv, 1);
45    argp = arguments;
46
47    while ((cp = *argp++)) {
48        if (*cp == '-') {
49            switch (smatch (++cp, switches)) {
50                case AMBIGSW:
51                    ambigsw (cp, switches);
52                    done (1);
53                case UNKWNSW:
54                    adios (NULL, "-%s unknown", cp);
55
56                case HELPSW:
57                    snprintf (buf, sizeof(buf), "%s [+folder] [switches]",
58                        invo_name);
59                    print_help (buf, switches, 1);
60                    done (1);
61                case VERSIONSW:
62                    print_version(invo_name);
63                    done (1);
64
65                case INTRSW:
66                    interactive = 1;
67                    continue;
68                case NINTRSW:
69                    interactive = 0;
70                    continue;
71            }
72        }
73        if (*cp == '+' || *cp == '@') {
74            if (folder)
75                adios (NULL, "only one folder at a time!");
76            else
77                folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
78        } else {
79            adios (NULL, "usage: %s [+folder] [switches]", invo_name);
80        }
81    }
82
83    if (!context_find ("path"))
84        free (path ("./", TFOLDER));
85    if (!folder) {
86        folder = getfolder (1);
87        defolder++;
88    }
89    if (strcmp (m_mailpath (folder), pwd ()) == 0)
90        adios (NULL, "sorry, you can't remove the current working directory");
91
92    if (interactive == -1)
93        interactive = defolder;
94
95    if (strchr (folder, '/') && (*folder != '/') && (*folder != '.')) {
96        for (cp = copy (folder, newfolder); cp > newfolder && *cp != '/'; cp--)
97            continue;
98        if (cp > newfolder)
99            *cp = '\0';
100        else
101            strncpy (newfolder, getfolder(0), sizeof(newfolder));
102    } else {
103        strncpy (newfolder, getfolder(0), sizeof(newfolder));
104    }
105
106    if (interactive) {
107        cp = concat ("Remove folder \"", folder, "\"? ", NULL);
108        if (!getanswer (cp))
109            done (0);
110        free (cp);
111    }
112
113    if (rmf (folder) == OK && strcmp (context_find (pfolder), newfolder)) {
114        printf ("[+%s now current]\n", newfolder);
115        context_replace (pfolder, newfolder);   /* update current folder */
116    }
117    context_save ();    /* save the context file */
118    done (0);
119}
120
121static int
122rmf (char *folder)
123{
124    int i, j, others;
125    register char *maildir;
126    char cur[BUFSIZ];
127    register struct dirent *dp;
128    register DIR *dd;
129
130    switch (i = chdir (maildir = m_maildir (folder))) {
131        case OK:
132            if (access (".", W_OK) != NOTOK && access ("..", W_OK) != NOTOK)
133                break;          /* fall otherwise */
134
135        case NOTOK:
136            snprintf (cur, sizeof(cur), "atr-%s-%s",
137                        current, m_mailpath (folder));
138            if (!context_del (cur)) {
139                printf ("[+%s de-referenced]\n", folder);
140                return OK;
141            }
142            advise (NULL, "you have no profile entry for the %s folder +%s",
143                    i == NOTOK ? "unreadable" : "read-only", folder);
144            return NOTOK;
145    }
146
147    if ((dd = opendir (".")) == NULL)
148        adios (NULL, "unable to read folder +%s", folder);
149    others = 0;
150
151    j = strlen(BACKUP_PREFIX);
152    while ((dp = readdir (dd))) {
153        switch (dp->d_name[0]) {
154            case '.':
155                if (strcmp (dp->d_name, ".") == 0
156                        || strcmp (dp->d_name, "..") == 0)
157                    continue;   /* else fall */
158
159            case ',':
160#ifdef MHE
161            case '+':
162#endif /* MHE */
163#ifdef UCI
164            case '_':
165            case '#':
166#endif /* UCI */
167                break;
168
169            default:
170                if (m_atoi (dp->d_name))
171                    break;
172                if (strcmp (dp->d_name, LINK) == 0
173                        || strncmp (dp->d_name, BACKUP_PREFIX, j) == 0)
174                    break;
175
176                admonish (NULL, "file \"%s/%s\" not deleted",
177                        folder, dp->d_name);
178                others++;
179                continue;
180        }
181        if (unlink (dp->d_name) == NOTOK) {
182            admonish (dp->d_name, "unable to unlink %s:", folder);
183            others++;
184        }
185    }
186
187    closedir (dd);
188
189    /*
190     * Remove any relevant private sequences
191     * or attributes from context file.
192     */
193    rma (folder);
194
195    chdir ("..");
196    if (others == 0 && remdir (maildir))
197        return OK;
198
199    advise (NULL, "folder +%s not removed", folder);
200    return NOTOK;
201}
202
203
204/*
205 * Remove all the (private) sequence information for
206 * this folder from the profile/context list.
207 */
208
209static void
210rma (char *folder)
211{
212    register int alen, j, plen;
213    register char *cp;
214    register struct node *np, *pp;
215
216    /* sanity check - check that context has been read */
217    if (defpath == NULL)
218        adios (NULL, "oops, context hasn't been read yet");
219
220    alen = strlen ("atr-");
221    plen = strlen (cp = m_mailpath (folder)) + 1;
222
223    /*
224     * Search context list for keys that look like
225     * "atr-something-folderpath", and remove them.
226     */
227    for (np = m_defs, pp = NULL; np; np = np->n_next) {
228        if (ssequal ("atr-", np->n_name)
229                && (j = strlen (np->n_name) - plen) > alen
230                && *(np->n_name + j) == '-'
231                && strcmp (cp, np->n_name + j + 1) == 0) {
232            if (!np->n_context)
233                admonish (NULL, "bug: context_del(key=\"%s\")", np->n_name);
234            if (pp) {
235                pp->n_next = np->n_next;
236                np = pp;
237            } else {
238                m_defs = np->n_next;
239            }
240            ctxflags |= CTXMOD;
241        } else {
242            pp = np;
243        }
244    }
245}
Note: See TracBrowser for help on using the repository browser.