X-Git-Url: https://git.cameronkatri.com/bsdgames-darwin.git/blobdiff_plain/94b5353c71e7246077d468afe68d51ce85fc213d..35f9239da17d9e247372b31eff7d50efb738dded:/fortune/strfile/strfile.c diff --git a/fortune/strfile/strfile.c b/fortune/strfile/strfile.c index 3b8b20d8..a0598505 100644 --- a/fortune/strfile/strfile.c +++ b/fortune/strfile/strfile.c @@ -1,4 +1,4 @@ -/* $NetBSD: strfile.c,v 1.3 1995/03/23 08:28:47 cgd Exp $ */ +/* $NetBSD: strfile.c,v 1.39 2020/04/29 20:45:05 nia Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,32 +32,45 @@ * SUCH DAMAGE. */ +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#ifdef __NetBSD__ +#include #ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; +__COPYRIGHT("@(#) Copyright (c) 1989, 1993\ + The Regents of the University of California. All rights reserved."); #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)strfile.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$NetBSD: strfile.c,v 1.3 1995/03/23 08:28:47 cgd Exp $"; +__RCSID("$NetBSD: strfile.c,v 1.39 2020/04/29 20:45:05 nia Exp $"); #endif #endif /* not lint */ +#endif /* __NetBSD__ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -# include -# include -# include -# include -# include "strfile.h" +#include "strfile.h" -# ifndef MAXPATHLEN -# define MAXPATHLEN 1024 -# endif /* MAXPATHLEN */ +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif /* MAXPATHLEN */ /* - * This program takes a file composed of strings seperated by + * This program takes a file composed of strings separated by * lines starting with two consecutive delimiting character (default * character is '%') and creates another file which consists of a table * describing the file (structure from "strfile.h"), a table of seek @@ -83,59 +92,52 @@ static char rcsid[] = "$NetBSD: strfile.c,v 1.3 1995/03/23 08:28:47 cgd Exp $"; * Added ordering options. */ -# define TRUE 1 -# define FALSE 0 - # define STORING_PTRS (Oflag || Rflag) # define CHUNKSIZE 512 -#ifdef lint -# define ALWAYS atoi("1") -#else -# define ALWAYS 1 -#endif -# define ALLOC(ptr,sz) if (ALWAYS) { \ +# define ALLOC(ptr,sz) do { \ if (ptr == NULL) \ - ptr = malloc((unsigned int) (CHUNKSIZE * sizeof *ptr)); \ + ptr = malloc(CHUNKSIZE * sizeof *ptr); \ else if (((sz) + 1) % CHUNKSIZE == 0) \ - ptr = realloc((void *) ptr, ((unsigned int) ((sz) + CHUNKSIZE) * sizeof *ptr)); \ - if (ptr == NULL) { \ - fprintf(stderr, "out of space\n"); \ - exit(1); \ - } \ - } else - -#ifdef NO_VOID -# define void char -#endif + ptr = realloc(ptr, ((sz) + CHUNKSIZE) * sizeof *ptr); \ + if (ptr == NULL) \ + err(1, "out of space"); \ + } while (0) typedef struct { char first; off_t pos; } STR; -char *Infile = NULL, /* input file name */ - Outfile[MAXPATHLEN] = "", /* output file name */ - Delimch = '%'; /* delimiting character */ +static char *Infile = NULL; /* input file name */ +static char Outfile[MAXPATHLEN] = ""; /* output file name */ +static char Delimch = '%'; /* delimiting character */ + +static int Sflag = 0; /* silent run flag */ +static int Oflag = 0; /* ordering flag */ +static int Iflag = 0; /* ignore case flag */ +static int Rflag = 0; /* randomize order flag */ +static int Xflag = 0; /* set rotated bit */ +static long Num_pts = 0; /* number of pointers/strings */ -int Sflag = FALSE; /* silent run flag */ -int Oflag = FALSE; /* ordering flag */ -int Iflag = FALSE; /* ignore case flag */ -int Rflag = FALSE; /* randomize order flag */ -int Xflag = FALSE; /* set rotated bit */ -long Num_pts = 0; /* number of pointers/strings */ +static off_t *Seekpts; -off_t *Seekpts; +static FILE *Sort_1, *Sort_2; /* pointers for sorting */ -FILE *Sort_1, *Sort_2; /* pointers for sorting */ +static STRFILE Tbl; /* statistics table */ -STRFILE Tbl; /* statistics table */ +static STR *Firstch; /* first chars of each string */ -STR *Firstch; /* first chars of each string */ -char *fgets(), *strcpy(), *strcat(); +static uint32_t h2nl(uint32_t h); +static void getargs(int argc, char **argv); +static void usage(void) __dead; +static void add_offset(FILE *fp, off_t off); +static void do_order(void); +static int cmp_str(const void *vp1, const void *vp2); +static void randomize(void); +static void fwrite_be_offt(off_t off, FILE *f); -void *malloc(), *realloc(); /* * main: @@ -146,38 +148,38 @@ void *malloc(), *realloc(); * CHUNKSIZE blocks; if the latter, we just write each pointer, * and then seek back to the beginning to write in the table. */ -main(ac, av) -int ac; -char **av; +int +main(int ac, char **av) { - register char *sp, dc; - register FILE *inf, *outf; - register off_t last_off, length, pos, *p; - register int first, cnt; - register char *nsp; - register STR *fp; - static char string[257]; + char *sp, dc; + FILE *inf, *outf; + off_t last_off, length, pos; + int first; + char *nsp; + STR *fp; + static char string[257]; + long i; + + /* sanity test */ + if (sizeof(uint32_t) != 4) + errx(1, "sizeof(uint32_t) != 4"); getargs(ac, av); /* evalute arguments */ dc = Delimch; - if ((inf = fopen(Infile, "r")) == NULL) { - perror(Infile); - exit(1); - } + if ((inf = fopen(Infile, "r")) == NULL) + err(1, "open `%s'", Infile); - if ((outf = fopen(Outfile, "w")) == NULL) { - perror(Outfile); - exit(1); - } + if ((outf = fopen(Outfile, "w")) == NULL) + err(1, "open `%s'", Outfile); if (!STORING_PTRS) - (void) fseek(outf, sizeof Tbl, 0); + (void) fseek(outf, sizeof Tbl, SEEK_SET); /* * Write the strings onto the file */ Tbl.str_longlen = 0; - Tbl.str_shortlen = (unsigned int) 0xffffffff; + Tbl.str_shortlen = (unsigned int) 0x7fffffff; Tbl.str_delim = dc; Tbl.str_version = VERSION; first = Oflag; @@ -185,30 +187,30 @@ char **av; last_off = 0; do { sp = fgets(string, 256, inf); - if (sp == NULL || sp[0] == dc && sp[1] == '\n') { + if (sp == NULL || (sp[0] == dc && sp[1] == '\n')) { pos = ftell(inf); length = pos - last_off - (sp ? strlen(sp) : 0); last_off = pos; if (!length) continue; add_offset(outf, pos); - if (Tbl.str_longlen < length) + if ((off_t)Tbl.str_longlen < length) Tbl.str_longlen = length; - if (Tbl.str_shortlen > length) + if ((off_t)Tbl.str_shortlen > length) Tbl.str_shortlen = length; first = Oflag; } else if (first) { - for (nsp = sp; !isalnum(*nsp); nsp++) + for (nsp = sp; !isalnum((unsigned char)*nsp); nsp++) continue; ALLOC(Firstch, Num_pts); fp = &Firstch[Num_pts - 1]; - if (Iflag && isupper(*nsp)) - fp->first = tolower(*nsp); + if (Iflag && isupper((unsigned char)*nsp)) + fp->first = tolower((unsigned char)*nsp); else fp->first = *nsp; fp->pos = Seekpts[Num_pts - 1]; - first = FALSE; + first = 0; } } while (sp != NULL); @@ -231,25 +233,27 @@ char **av; if (Num_pts == 2) puts("There was 1 string"); else - printf("There were %d strings\n", Num_pts - 1); - printf("Longest string: %lu byte%s\n", Tbl.str_longlen, + printf("There were %d strings\n", (int)(Num_pts - 1)); + printf("Longest string: %lu byte%s\n", (unsigned long)Tbl.str_longlen, Tbl.str_longlen == 1 ? "" : "s"); - printf("Shortest string: %lu byte%s\n", Tbl.str_shortlen, + printf("Shortest string: %lu byte%s\n", (unsigned long)Tbl.str_shortlen, Tbl.str_shortlen == 1 ? "" : "s"); } - (void) fseek(outf, (off_t) 0, 0); - Tbl.str_version = htonl(Tbl.str_version); - Tbl.str_numstr = htonl(Num_pts - 1); - Tbl.str_longlen = htonl(Tbl.str_longlen); - Tbl.str_shortlen = htonl(Tbl.str_shortlen); - Tbl.str_flags = htonl(Tbl.str_flags); + (void) fseek(outf, (off_t) 0, SEEK_SET); + Tbl.str_version = h2nl(Tbl.str_version); + Tbl.str_numstr = h2nl(Num_pts - 1); + Tbl.str_longlen = h2nl(Tbl.str_longlen); + Tbl.str_shortlen = h2nl(Tbl.str_shortlen); + Tbl.str_flags = h2nl(Tbl.str_flags); (void) fwrite((char *) &Tbl, sizeof Tbl, 1, outf); if (STORING_PTRS) { - for (p = Seekpts, cnt = Num_pts; cnt--; ++p) - *p = htonl(*p); - (void) fwrite((char *) Seekpts, sizeof *Seekpts, (int) Num_pts, outf); + for (i = 0; i < Num_pts; i++) + fwrite_be_offt(Seekpts[i], outf); } + fflush(outf); + if (ferror(outf)) + err(1, "fwrite %s", Outfile); (void) fclose(outf); exit(0); } @@ -257,15 +261,15 @@ char **av; /* * This routine evaluates arguments from the command line */ -getargs(argc, argv) -int argc; -char **argv; +static void +getargs(int argc, char **argv) { - extern char *optarg; - extern int optind; int ch; + extern int optind; + extern char *optarg; + size_t len; - while ((ch = getopt(argc, argv, "c:iorsx")) != EOF) + while ((ch = getopt(argc, argv, "c:iorsx")) != -1) switch(ch) { case 'c': /* new delimiting char */ Delimch = *optarg; @@ -297,23 +301,36 @@ char **argv; if (*argv) { Infile = *argv; - if (*++argv) - (void) strcpy(Outfile, *argv); + if (*++argv) { + len = strlen(*argv); + if (len >= sizeof(Outfile)) { + puts("Bad output filename"); + usage(); + } + (void) memcpy(Outfile, *argv, len + 1); + } } if (!Infile) { puts("No input file name"); usage(); } if (*Outfile == '\0') { + len = strlen(Infile) + sizeof(".dat"); + if (len > sizeof(Outfile)) { + puts("Bad input filename"); + usage(); + } (void) strcpy(Outfile, Infile); (void) strcat(Outfile, ".dat"); } } -usage() +static void +usage(void) { (void) fprintf(stderr, - "strfile [-iorsx] [-c char] sourcefile [datafile]\n"); + "Usage: %s [-iorsx] [-c char] sourcefile [datafile]\n", + getprogname()); exit(1); } @@ -321,15 +338,12 @@ usage() * add_offset: * Add an offset to the list, or write it out, as appropriate. */ -add_offset(fp, off) -FILE *fp; -off_t off; +static void +add_offset(FILE *fp, off_t off) { - off_t net; if (!STORING_PTRS) { - net = htonl(off); - fwrite(&net, 1, sizeof net, fp); + fwrite_be_offt(off, fp); } else { ALLOC(Seekpts, Num_pts + 1); Seekpts[Num_pts] = off; @@ -341,12 +355,12 @@ off_t off; * do_order: * Order the strings alphabetically (possibly ignoring case). */ -do_order() +static void +do_order(void) { - register int i; - register off_t *lp; - register STR *fp; - extern int cmp_str(); + int i; + off_t *lp; + STR *fp; Sort_1 = fopen(Infile, "r"); Sort_2 = fopen(Infile, "r"); @@ -361,36 +375,15 @@ do_order() Tbl.str_flags |= STR_ORDERED; } -/* - * cmp_str: - * Compare two strings in the file - */ -char * -unctrl(c) -char c; +static int +cmp_str(const void *vp1, const void *vp2) { - static char buf[3]; - - if (isprint(c)) { - buf[0] = c; - buf[1] = '\0'; - } - else if (c == 0177) { - buf[0] = '^'; - buf[1] = '?'; - } - else { - buf[0] = '^'; - buf[1] = c + 'A' - 1; - } - return buf; -} + const STR *p1, *p2; + int c1, c2; + int n1, n2; -cmp_str(p1, p2) -STR *p1, *p2; -{ - register int c1, c2; - register int n1, n2; + p1 = (const STR *)vp1; + p2 = (const STR *)vp2; # define SET_N(nf,ch) (nf = (ch == '\n')) # define IS_END(ch,nf) (ch == Delimch && nf) @@ -400,11 +393,11 @@ STR *p1, *p2; if (c1 != c2) return c1 - c2; - (void) fseek(Sort_1, p1->pos, 0); - (void) fseek(Sort_2, p2->pos, 0); + (void) fseek(Sort_1, p1->pos, SEEK_SET); + (void) fseek(Sort_2, p2->pos, SEEK_SET); - n1 = FALSE; - n2 = FALSE; + n1 = 0; + n2 = 0; while (!isalnum(c1 = getc(Sort_1)) && c1 != '\0') SET_N(n1, c1); while (!isalnum(c2 = getc(Sort_2)) && c2 != '\0') @@ -437,14 +430,14 @@ STR *p1, *p2; * not to randomize across delimiter boundaries. All * randomization is done within each block. */ -randomize() +static void +randomize(void) { - register int cnt, i; - register off_t tmp; - register off_t *sp; - extern time_t time(); + int cnt, i; + off_t tmp; + off_t *sp; - srandom((int)(time((time_t *) NULL) + getpid())); + srandom((int)(time(NULL) + getpid())); Tbl.str_flags |= STR_RANDOM; cnt = Tbl.str_numstr; @@ -460,3 +453,36 @@ randomize() sp[i] = tmp; } } + +/* + * fwrite_be_offt: + * Write out the off paramater as a 64 bit big endian number + */ + +static void +fwrite_be_offt(off_t off, FILE *f) +{ + int i; + unsigned char c[8]; + + for (i = 7; i >= 0; i--) { + c[i] = off & 0xff; + off >>= 8; + } + fwrite(c, sizeof(c), 1, f); +} + +static uint32_t +h2nl(uint32_t h) +{ + unsigned char c[4]; + uint32_t rv; + + c[0] = (h >> 24) & 0xff; + c[1] = (h >> 16) & 0xff; + c[2] = (h >> 8) & 0xff; + c[3] = (h >> 0) & 0xff; + memcpy(&rv, c, sizeof rv); + + return (rv); +}