]> granicus.if.org Git - fortune-mod/blob - fortune-mod/util/unstr.c
consolidate includes.
[fortune-mod] / fortune-mod / util / unstr.c
1 /*      $NetBSD: unstr.c,v 1.3 1995/03/23 08:29:00 cgd Exp $    */
2
3 /*-
4  * Copyright (c) 1991, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Ken Arnold.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #if 0
40 #ifndef lint
41 static char copyright[] =
42 "@(#) Copyright (c) 1991, 1993\n\
43         The Regents of the University of California.  All rights reserved.\n";
44
45 #endif /* not lint */
46
47 #ifndef lint
48 static char sccsid[] = "@(#)unstr.c     8.1 (Berkeley) 5/31/93";
49
50 #endif /* not lint */
51 #endif /* comment out the dreck, kill the warnings */
52
53 /*
54  *    This program un-does what "strfile" makes, thereby obtaining the
55  * original file again.  This can be invoked with the name of the output
56  * file, the input file, or both. If invoked with only a single argument
57  * ending in ".dat", it is pressumed to be the input file and the output
58  * file will be the same stripped of the ".dat".  If the single argument
59  * doesn't end in ".dat", then it is presumed to be the output file, and
60  * the input file is that name prepended by a ".dat".  If both are given
61  * they are treated literally as the input and output files.
62  *
63  *      Ken Arnold              Aug 13, 1978
64  */
65
66 /*
67  * Umm.  Well, when I got this thing, it didn't work like that.  It now
68  * treats the *first* filename listed as the name of the datafile; if
69  * the file happens to have an extension, that's stripped off and the
70  * result is the name of the strings file.  If there is no extension, then
71  * the datafile has '.dat' added, and the strings file is the filename.
72  * The only problem with this is if you happen to have a strings file
73  * with a dot in it--in that case, specify the dat file fully.
74  *
75  * The program also now accepts an optional second filename, which is the
76  * name of the output file; if not specified, it dumps to stdout.
77  *
78  * It can also take one parameter, which defines a new separator character.
79  * This was added chiefly in order to avoid having to run sed over a
80  * strings file; unstr *can* do it easily, so it should.
81  *
82  * We also had to add some code to make the special cases of a null fortune
83  * (two separators on successive lines, a common enough error when editing
84  * a strings file) and no trailing separator be treated properly.  Unstr
85  * now writes out a separator string at the end of a file; strfile does
86  * not consider the null string following this to be a fortune.  Be careful
87  * not to put an extra newline after the required last newline--if so, you'll
88  * get a fortune that contains nothing but a newline.  Karo syrup, syrup.
89  * For the gory details, and lots of cussing, see strfile.c
90  */
91
92 #include "fortune-mod-common.h"
93
94 static char *Infile,                   /* name of input file */
95   Datafile[MAXPATHLEN],         /* name of data file */
96   Delimch,                      /* delimiter character */
97   Outfile[MAXPATHLEN];
98
99 static char NewDelch = '\0';           /* a replacement delimiter character */
100
101 static FILE *Inf, *Dataf, *Outf;
102
103 /* ARGSUSED */
104 static void getargs(int ac, char *av[])
105 {
106     char *extc;
107     int ch;
108
109     while ((ch = getopt(ac, av, "c:")) != EOF)
110         switch (ch)
111           {
112           case 'c':
113               NewDelch = *optarg;
114               if (!isascii(NewDelch))
115               {
116                   fprintf(stderr, "Bad delimiting characher: '\\%o'\n", (unsigned int)NewDelch);
117               }
118               break;
119           case '?':
120           default:
121               fprintf(stderr, "Usage:\n\tunstr [-c C] datafile[.ext] [outputfile]\n");
122               exit(1);
123           }
124
125     av += optind;
126
127     if (*av)
128     {
129         Infile = *av;
130         fprintf(stderr, "Input file: %s\n", Infile);
131         if (!strrchr(Infile, '.'))
132         {
133             strcpy(Datafile, Infile);
134             strcat(Datafile, ".dat");
135         }
136         else
137         {
138             strcpy(Datafile, Infile);
139             extc = strrchr(Infile, '.');
140             *extc = '\0';
141         }
142         if (*++av)
143         {
144             strcpy(Outfile, *av);
145             fprintf(stderr, "Output file: %s\n", Outfile);
146         }
147     }
148     else
149     {
150         fprintf(stderr, "No input file name\n");
151         fprintf(stderr, "Usage:\n\tunstr [-c C] datafile[.ext] [outputfile]\n");
152         exit(1);
153     }
154     if (!strcmp(Infile, Outfile))
155     {
156         fprintf(stderr, "The input file for strings (%s) must be different from the output file (%s)\n", Infile, Outfile);
157         exit(1);
158     }
159 }
160
161 static void order_unstr(register STRFILE *tbl)
162 {
163     register uint32_t i;
164     register char *sp;
165     auto int32_t pos;
166     char buf[BUFSIZ];
167     int printedsome;
168
169     for (i = 0; i <= tbl->str_numstr; i++)
170     {
171         fread((char *) &pos, 1, sizeof pos, Dataf);
172         fseek(Inf, ntohl((uint32_t)pos), 0);
173         printedsome = 0;
174         for (;;)
175         {
176             sp = fgets(buf, sizeof buf, Inf);
177             if (sp == NULL || STR_ENDSTRING(sp, *tbl))
178             {
179                 if (sp || printedsome)
180                     fprintf(Outf, "%c\n", Delimch);
181                 break;
182             }
183             else
184             {
185                 printedsome = 1;
186                 fputs(sp, Outf);
187             }
188         }
189     }
190 }
191
192 int main(int ac, char **av)
193 {
194     static STRFILE tbl;         /* description table */
195
196     getargs(ac, av);
197     if ((Inf = fopen(Infile, "r")) == NULL)
198     {
199         perror(Infile);
200         exit(1);
201     }
202     if ((Dataf = fopen(Datafile, "r")) == NULL)
203     {
204         perror(Datafile);
205         exit(1);
206     }
207     if (*Outfile == '\0')
208         Outf = stdout;
209     else if ((Outf = fopen(Outfile, "w+")) == NULL)
210     {
211         perror(Outfile);
212         exit(1);
213     }
214     fread(&tbl.str_version,  sizeof(tbl.str_version),  1, Dataf);
215     fread(&tbl.str_numstr,   sizeof(tbl.str_numstr),   1, Dataf);
216     fread(&tbl.str_longlen,  sizeof(tbl.str_longlen),  1, Dataf);
217     fread(&tbl.str_shortlen, sizeof(tbl.str_shortlen), 1, Dataf);
218     fread(&tbl.str_flags,    sizeof(tbl.str_flags),    1, Dataf);
219     fread( tbl.stuff,        sizeof(tbl.stuff),        1, Dataf);
220     if (!(tbl.str_flags & (STR_ORDERED | STR_RANDOM)) && (!NewDelch))
221     {
222         fprintf(stderr, "nothing to do -- table in file order\n");
223         exit(1);
224     }
225     if (NewDelch)
226         Delimch = NewDelch;
227     else
228         Delimch = (char)tbl.str_delim;
229     order_unstr(&tbl);
230     fclose(Inf);
231     fclose(Dataf);
232     fclose(Outf);
233     exit(0);
234 }