[comp.unix.questions] Okay, here's a toughie for you...

edh@ux.acs.umn.edu (Eric D. Hendrickson) (11/30/90)

The below program does not work.  It seg faults in the last for loop.  Can
someone see what is wrong here?  I suspect I have made a mistake using the
pointers somewhere, but after much trial and error, little progress has
been made.  Perhaps you can see what it is...

thanks,
		Eric
(btw -- if this is not a good question for comp.lang.c, please let me know)

/*
 *	PrintCap Utility (skeleton test version)
 *	Copyright 1990
 *	placed in the public domain
 *	Eric Hendrickson <{edh,eric}@ux.acs.umn.edu>
 *	November, 1990
 */

#define MAXPRINTERS	100		/* Max of 100 printers */
#define PRINTCAP	"/etc/printcap"
#define PROGRAM		"pcu"

#include <stdio.h>
#include <sys/types.h>
#include <string.h>

main()
{
    char *grep = "cm";

    chores(grep);
}

/* extract the printcap setting requested */
char **
extract(grep)
char grep[];
{
    FILE *fp;
    int i = 0, j = 0;
    char found[MAXPRINTERS][BUFSIZ];	/* holds found entries */
    char line[BUFSIZ];			/* holds search string */
    char *p, *pc = PRINTCAP;

    if ((fp = fopen(pc, "r")) != NULL) {
	while (fgets(line, sizeof(line), fp)) {
	    if (line[0] == '\t') {	/* we have a line to scan */
		if (p = (char *)strstr(line, grep)) { /* we have a candidate */
		    if ((i = strcspn(p, (char *)"=#")) != 2) { /* guess not */
			continue;
		    }
		    p+=3;		/* skip the prefix */
		    strtok(p, (char *)":"); /* chop off the trailing section */
		    strncpy((char *)found[j++], p, strlen(p));
		}
	    }
	}
	fclose(fp);
	return((char **)found);
    } else {
	fprintf(stderr, "%s: unable to open %s\n", PROGRAM, PRINTCAP);
	exit(1);
    }
}

/*
 * perform requested hyphen options
 */
int
chores(grep)
char *grep;
{
    static char **gots;
    char **extract();

    gots = (char **)extract(grep);
    for( ; **gots != (char)'\0'; printf("%s\n", gots++)) ;
}

/*
 * below are two seperate functions from comp.sources.unix, I keep them
 * in seperate from the main program.
 */

/*
 * strstr - find first occurrence of wanted in s
 */

#define	NULL	0

char *				/* found string, or NULL if none */
strstr(s, wanted)
char *s;
char *wanted;
{
	register char *scan;
	register int len;
	register char firstc;
	extern int strcmp();
	extern int strlen();

	/*
	 * The odd placement of the two tests is so "" is findable.
	 * Also, we inline the first char for speed.
	 * The ++ on scan has been moved down for optimization.
	 */
	firstc = *wanted;
	len = strlen(wanted);
	for (scan = s; *scan != firstc || strncmp(scan, wanted, len) != 0; )
		if (*scan++ == '\0')
			return(NULL);
	return(scan);
}

/*
 * strcspn - find length of initial segment of s consisting entirely
 * of characters not from reject
 */

int
strcspn(s, reject)
char *s;
char *reject;
{
	register char *scan;
	register char *rscan;
	register int count;

	count = 0;
	for (scan = s; *scan != '\0'; scan++) {
		for (rscan = reject; *rscan != '\0';)	/* ++ moved down. */
			if (*scan == *rscan++)
				return(count);
		count++;
	}
	return(count);
}
-- 
/----------"Oh carrots are divine, you get a dozen for dime, its maaaagic."--
|Eric (the "Mentat-Philosopher") Hendrickson	  Academic Computing Services
|edh@ux.acs.umn.edu	   The game is afoot!	      University of Minnesota
\-"What does 'masochist' and 'amnesia' mean?   Beats me, I don't remember."--