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

Revision 12455, 4.8 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 * packf.c -- pack a nmh folder into a file
4 *
5 * $Id: packf.c,v 1.1.1.1 1999-02-07 18:14:15 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <fcntl.h>
10#include <h/dropsbr.h>
11#include <errno.h>
12
13/*
14 * We allocate space for messages (msgs array)
15 * this number of elements at a time.
16 */
17#define MAXMSGS  256
18
19
20static struct swit switches[] = {
21#define FILESW         0
22    { "file name", 0 },
23#define MBOXSW         1
24    { "mbox", 0 },
25#define MMDFSW         2
26    { "mmdf", 0 },
27#define VERSIONSW      3
28    { "version", 0 },
29#define HELPSW         4
30    { "help", 4 },
31    { NULL, 0 }
32};
33
34extern int errno;
35
36static int md = NOTOK;
37static int mbx_style = MBOX_FORMAT;
38static int mapping = 0;
39
40char *file = NULL;
41
42
43int
44main (int argc, char **argv)
45{
46    int nummsgs, maxmsgs, fd, msgnum;
47    char *cp, *maildir, *msgnam, *folder = NULL, buf[BUFSIZ];
48    char **argp, **arguments, **msgs;
49    struct msgs *mp;
50    struct stat st;
51
52#ifdef LOCALE
53    setlocale(LC_ALL, "");
54#endif
55    invo_name = r1bindex (argv[0], '/');
56
57    /* read user profile/context */
58    context_read();
59
60    arguments = getarguments (invo_name, argc, argv, 1);
61    argp = arguments;
62
63    /* Allocate the initial space to record message
64     * names and ranges.
65     */
66    nummsgs = 0;
67    maxmsgs = MAXMSGS;
68    if (!(msgs = (char **) malloc ((size_t) (maxmsgs * sizeof(*msgs)))))
69        adios (NULL, "unable to allocate storage");
70
71    /*
72     * Parse arguments
73     */
74    while ((cp = *argp++)) {
75        if (*cp == '-') {
76            switch (smatch (++cp, switches)) {
77                case AMBIGSW:
78                    ambigsw (cp, switches);
79                    done (1);
80                case UNKWNSW:
81                    adios (NULL, "-%s unknown", cp);
82
83                case HELPSW:
84                    snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
85                        invo_name);
86                    print_help (buf, switches, 1);
87                    done (1);
88                case VERSIONSW:
89                    print_version(invo_name);
90                    done (1);
91
92                case FILESW:
93                    if (file)
94                        adios (NULL, "only one file at a time!");
95                    if (!(file = *argp++) || *file == '-')
96                        adios (NULL, "missing argument to %s", argp[-2]);
97                    continue;
98
99                case MBOXSW:
100                    mbx_style = MBOX_FORMAT;
101                    mapping = 0;
102                    continue;
103                case MMDFSW:
104                    mbx_style = MMDF_FORMAT;
105                    mapping = 1;
106                    continue;
107            }
108        }
109        if (*cp == '+' || *cp == '@') {
110            if (folder)
111                adios (NULL, "only one folder at a time!");
112            folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
113        } else {
114            /*
115             * Check if we need to allocate more space
116             * for message name/ranges.
117             */
118            if (nummsgs >= maxmsgs) {
119                maxmsgs += MAXMSGS;
120                if (!(msgs = (char **) realloc (msgs,
121                        (size_t) (maxmsgs * sizeof(*msgs)))))
122                    adios (NULL, "unable to reallocate msgs storage");
123            }
124            msgs[nummsgs++] = cp;
125        }
126    }
127
128    if (!file)
129        file = "./msgbox";
130    file = path (file, TFILE);
131
132    /*
133     * Check if file to be created (or appended to)
134     * exists.  If not, ask for confirmation.
135     */
136    if (stat (file, &st) == NOTOK) {
137        if (errno != ENOENT)
138            adios (file, "error on file");
139        cp = concat ("Create file \"", file, "\"? ", NULL);
140        if (!getanswer (cp))
141            done (1);
142        free (cp);
143    }
144
145    if (!context_find ("path"))
146        free (path ("./", TFOLDER));
147
148    /* default is to pack whole folder */
149    if (!nummsgs)
150        msgs[nummsgs++] = "all";
151
152    if (!folder)
153        folder = getfolder (1);
154    maildir = m_maildir (folder);
155
156    if (chdir (maildir) == NOTOK)
157        adios (maildir, "unable to change directory to ");
158
159    /* read folder and create message structure */
160    if (!(mp = folder_read (folder)))
161        adios (NULL, "unable to read folder %s", folder);
162
163    /* check for empty folder */
164    if (mp->nummsg == 0)
165        adios (NULL, "no messages in %s", folder);
166
167    /* parse all the message ranges/sequences and set SELECTED */
168    for (msgnum = 0; msgnum < nummsgs; msgnum++)
169        if (!m_convert (mp, msgs[msgnum]))
170            done (1);
171    seq_setprev (mp);   /* set the previous-sequence */
172
173    /* open and lock new maildrop file */
174    if ((md = mbx_open(file, mbx_style, getuid(), getgid(), m_gmprot())) == NOTOK)
175        adios (file, "unable to open");
176
177    /* copy all the SELECTED messages to the file */
178    for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
179        if (is_selected(mp, msgnum)) {
180            if ((fd = open (msgnam = m_name (msgnum), O_RDONLY)) == NOTOK) {
181                admonish (msgnam, "unable to read message");
182                break;
183            }
184
185            if (mbx_copy (file, mbx_style, md, fd, mapping, NULL, 1) == NOTOK)
186                adios (file, "error writing to file");
187
188            close (fd);
189        }
190
191    /* close and unlock maildrop file */
192    mbx_close (file, md);
193
194    context_replace (pfolder, folder);  /* update current folder         */
195    if (mp->hghsel != mp->curmsg)
196        seq_setcur (mp, mp->lowsel);
197    seq_save (mp);
198    context_save ();                    /* save the context file         */
199    folder_free (mp);                   /* free folder/message structure */
200    done (0);
201}
202
203void
204done (int status)
205{
206    mbx_close (file, md);
207    exit (status);
208}
Note: See TracBrowser for help on using the repository browser.