char *p, *s, *infile;
const char *s; char *p, *infile;
main(int argc, char *argv[]){	FTS *ftsp;	FTSENT *entry;	struct stat osb;	const struct compressor *method;	char *p, *s, *infile;	char outfile[MAXPATHLEN], _infile[MAXPATHLEN], suffix[16];	char *nargv[512];	/* some estimate based on ARG_MAX */	int exists, oreg, ch, error, i, rc, oflag;	bits = cat = oflag = decomp = 0;	p = __progname;	if (p[0] == 'g') {		method = M_DEFLATE;		bits = 6;		p++;	} else		method = M_COMPRESS;	decomp = 0;	if (!strcmp(p, "zcat")) {		decomp++;		cat = 1;	} else {		if (p[0] == 'u' && p[1] == 'n') {			p += 2;			decomp++;		}		if (strcmp(p, "zip") &&		    strcmp(p, "compress"))			errx(1, "unknown program name");	}	strlcpy(suffix, method->suffix, sizeof(suffix));	nargv[0] = NULL;	if ((s = getenv("GZIP")) != NULL) {		char *last;		nargv[0] = *argv++;		for (i = 1, (p = strtok_r(s, " ", &last)); p;		    (p = strtok_r(NULL, " ", &last)), i++)			if (i < sizeof(nargv)/sizeof(nargv[1]) - argc - 1)				nargv[i] = p;			else {				errx(1, "GZIP is too long");			}		argc += i - 1;		while ((nargv[i++] = *argv++))			;		argv = nargv;	}	while ((ch = getopt_long(argc, argv, OPTSTRING, longopts, NULL)) != -1)		switch(ch) {		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':			method = M_DEFLATE;			strlcpy(suffix, method->suffix, sizeof(suffix));			bits = ch - '0';			break;		case 'a':			warnx("option -a is ignored on this system");			break;		case 'b':			bits = strtol(optarg, &p, 10);			/*			 * POSIX 1002.3 says 9 <= bits <= 14 for portable			 * apps, but says the implementation may allow			 * greater.			 */			if (*p)				errx(1, "illegal bit count -- %s", optarg);			break;		case 'c':			cat = 1;			break;		case 'd':		/* Backward compatible. */			decomp++;			break;		case 'f':			force++;			break;		case 'g':			method = M_DEFLATE;			strlcpy(suffix, method->suffix, sizeof(suffix));			bits = 6;			break;		case 'l':			list++;			break;		case 'n':			nosave++;			break;		case 'N':			nosave = 0;	/* XXX not yet */			break;		case 'O':			method = M_COMPRESS;			strlcpy(suffix, method->suffix, sizeof(suffix));			break;		case 'o':			if (strlcpy(outfile, optarg,			    sizeof(outfile)) >= sizeof(outfile))				errx(1, "-o argument is too long");			oflag = 1;			break;		case 'q':			verbose = -1;			break;		case 'S':			p = suffix;			if (optarg[0] != '.')				*p++ = '.';			strlcpy(p, optarg, sizeof(suffix) - (p - suffix));			p = optarg;			break;		case 't':			testmode = 1;			decomp++;			break;		case 'V':			printf("%s\n%s\n%s\n", main_rcsid,			    z_rcsid, gz_rcsid);			exit (0);		case 'v':			verbose++;			break;		case 'L':			fputs(copyright, stderr);			fputs(license, stderr);			exit (0);		case 'r':			recurse++;			break;		case 'h':			usage(0);			break;		default:			usage(1);		}	argc -= optind;	argv += optind;	if (argc == 0) {		if (nargv[0] == NULL)			argv = nargv;		/* XXX - make sure we don't oflow nargv in $GZIP case (millert) */		argv[0] = "/dev/stdin";		argv[1] = NULL;		pipin++;		cat = 1;	} else {		for (i = 0; i < argc; i++) {			if (argv[i][0] == '-' && argv[i][1] == '\0') {				argv[i] = "/dev/stdin";				pipin++;				cat = 1;			}		}	}	if (oflag && (recurse || argc > 1))		errx(1, "-o option may only be used with a single input file");	if ((cat && argc) + testmode + oflag > 1)		errx(1, "may not mix -o, -c, or -t options");	if ((ftsp = fts_open(argv, FTS_PHYSICAL|FTS_NOCHDIR, 0)) == NULL)		err(1, NULL);	/* XXX - set rc in cases where we "continue" below? */	for (rc = 0; (entry = fts_read(ftsp)) != NULL;) {		infile = entry->fts_path;		switch (entry->fts_info) {		case FTS_D:			if (!recurse) {				warnx("%s is a directory: ignored",				    infile);				fts_set(ftsp, entry, FTS_SKIP);			}			continue;		case FTS_DP:			continue;		case FTS_NS:			/*			 * If file does not exist and has no suffix,			 * tack on the default suffix and try that.			 */			/* XXX - is overwriting fts_statp legal? (millert) */			if (entry->fts_errno == ENOENT &&			    strchr(entry->fts_accpath, '.') == NULL &&			    snprintf(_infile, sizeof(_infile), "%s%s", infile,			    suffix) < sizeof(_infile) &&			    stat(_infile, entry->fts_statp) == 0 &&			    S_ISREG(entry->fts_statp->st_mode)) {				infile = _infile;				break;			}		case FTS_ERR:		case FTS_DNR:			warnx("%s: %s", infile, strerror(entry->fts_errno));			error = 1;			continue;		default:			if (!S_ISREG(entry->fts_statp->st_mode) && !pipin) {				warnx("%s not a regular file%s",				    infile, cat ? "" : ": unchanged");				continue;			}			break;		}		if (testmode)			strlcpy(outfile, _PATH_DEVNULL, sizeof outfile);		else if (cat)			strlcpy(outfile, "/dev/stdout", sizeof outfile);		else if (!oflag) {			if (decomp) {				if (set_outfile(infile, outfile,				    sizeof outfile) == NULL) {					if (!recurse)						warnx("%s: unknown suffix: "						    "ignored", infile);					continue;				}			} else {				if (snprintf(outfile, sizeof(outfile),				    "%s%s", infile, suffix) >= sizeof(outfile)) {					warnx("%s%s: name too long",					    infile, suffix);					continue;				}			}		}		exists = !stat(outfile, &osb);		if (!force && exists && S_ISREG(osb.st_mode) &&		    !permission(outfile))			continue;		oreg = !exists || S_ISREG(osb.st_mode);		if (verbose > 0)			fprintf(stderr, "%s:\t", infile);		error = (decomp ? decompress : compress)			(infile, outfile, method, bits, entry->fts_statp);		if (!error && !cat && !testmode && stat(outfile, &osb) == 0) {			if (!force && !decomp &&			    osb.st_size >= entry->fts_statp->st_size) {				if (verbose > 0)					fprintf(stderr, "file would grow; "					    "left unmodified\n");				error = 1;				rc = rc ? rc : 2;			} else {				setfile(outfile, entry->fts_statp);				if (unlink(infile) && verbose >= 0)					warn("input: %s", infile);				if (verbose > 0) {					u_int ratio;					ratio = (1000 * osb.st_size)					    / entry->fts_statp->st_size;					fprintf(stderr, "%u", ratio / 10);					if (ratio % 10)						fprintf(stderr, ".%u",						    ratio % 10);					fputc('%', stderr);					fputc(' ', stderr);				}			}		}		if (error > 0 && oreg && unlink(outfile) && errno != ENOENT &&		    verbose >= 0) {			if (force) {				warn("output: %s", outfile);				rc = 1;			} else				err(1, "output: %s", outfile);		} else if (!error && verbose > 0)			fputs("OK\n", stderr);	}	exit(rc);}