if (read(ifd, i_womp, (size_t) i_size) != i_size) { close(ifd);	 free(i_womp);	 return false;
i_womp = mmap(NULL, i_size, PROT_READ, MAP_FILE, ifd, 0); if (i_womp == MAP_FAILED) { perror("mmap failed"); i_womp = NULL; return false;
plan_a(const char *filename){	int		ifd, statfailed;	char		*s, lbuf[MAXLINELEN];	LINENUM		iline;	struct stat	filestat;	if (filename == NULL || *filename == '\0')		return false;	statfailed = stat(filename, &filestat);	if (statfailed && ok_to_create_file) {		if (verbose)			say("(Creating file %s...)\n", filename);		/*		 * in check_patch case, we still display `Creating file' even		 * though we're not. The rule is that -C should be as similar		 * to normal patch behavior as possible		 */		if (check_only)			return true;		makedirs(filename, true);		close(creat(filename, 0666));		statfailed = stat(filename, &filestat);	}	if (statfailed && check_only)		fatal("%s not found, -C mode, can't probe further\n", filename);	/* For nonexistent or read-only files, look for RCS or SCCS versions.  */	if (statfailed ||	    /* No one can write to it.  */	    (filestat.st_mode & 0222) == 0 ||	    /* I can't write to it.  */	    ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) {		char	*cs = NULL, *filebase, *filedir;		struct stat	cstat;		filebase = basename(filename);		filedir = dirname(filename);		/* Leave room in lbuf for the diff command.  */		s = lbuf + 20;#define try(f, a1, a2, a3) \	(snprintf(s, sizeof lbuf - 20, f, a1, a2, a3), stat(s, &cstat) == 0)		if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||		    try("%s/RCS/%s%s", filedir, filebase, "") ||		    try("%s/%s%s", filedir, filebase, RCSSUFFIX)) {			snprintf(buf, sizeof buf, CHECKOUT, filename);			snprintf(lbuf, sizeof lbuf, RCSDIFF, filename);			cs = "RCS";		} else if (try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) ||		    try("%s/%s%s", filedir, SCCSPREFIX, filebase)) {			snprintf(buf, sizeof buf, GET, s);			snprintf(lbuf, sizeof lbuf, SCCSDIFF, s, filename);			cs = "SCCS";		} else if (statfailed)			fatal("can't find %s\n", filename);		/*		 * else we can't write to it but it's not under a version		 * control system, so just proceed.		 */		if (cs) {			if (!statfailed) {				if ((filestat.st_mode & 0222) != 0)					/* The owner can write to it.  */					fatal("file %s seems to be locked "					    "by somebody else under %s\n",					    filename, cs);				/*				 * It might be checked out unlocked.  See if				 * it's safe to check out the default version				 * locked.				 */				if (verbose)					say("Comparing file %s to default "					    "%s version...\n",					    filename, cs);				if (system(lbuf))					fatal("can't check out file %s: "					    "differs from default %s version\n",					    filename, cs);			}			if (verbose)				say("Checking out file %s from %s...\n",				    filename, cs);			if (system(buf) || stat(filename, &filestat))				fatal("can't check out file %s from %s\n",				    filename, cs);		}	}	filemode = filestat.st_mode;	if (!S_ISREG(filemode))		fatal("%s is not a normal file--can't patch\n", filename);	i_size = filestat.st_size;	if (out_of_mem) {		set_hunkmax();	/* make sure dynamic arrays are allocated */		out_of_mem = false;		return false;	/* force plan b because plan a bombed */	}	if (i_size > SIZE_MAX - 2)		fatal("block too large to allocate");	i_womp = malloc((size_t)(i_size + 2));	if (i_womp == NULL)		return false;	if ((ifd = open(filename, O_RDONLY)) < 0)		pfatal("can't open file %s", filename);	if (read(ifd, i_womp, (size_t) i_size) != i_size) {		close(ifd);	/* probably means i_size > 15 or 16 bits worth */		free(i_womp);	/* at this point it doesn't matter if i_womp was */		return false;	/* undersized. */	}	close(ifd);	if (i_size && i_womp[i_size - 1] != '\n')		i_womp[i_size++] = '\n';	i_womp[i_size] = '\0';	/* count the lines in the buffer so we know how many pointers we need */	iline = 0;	for (s = i_womp; *s; s++) {		if (*s == '\n')			iline++;	}	i_ptr = (char **) malloc((iline + 2) * sizeof(char *));	if (i_ptr == NULL) {	/* shucks, it was a near thing */		free(i_womp);		return false;	}	/* now scan the buffer and build pointer array */	iline = 1;	i_ptr[iline] = i_womp;	for (s = i_womp; *s; s++) {		if (*s == '\n')			i_ptr[++iline] = s + 1;	/* these are NOT NUL terminated */	}	input_lines = iline - 1;	/* now check for revision, if any */	if (revision != NULL) {		if (!rev_in_string(i_womp)) {			if (force) {				if (verbose)					say("Warning: this file doesn't appear "					    "to be the %s version--patching anyway.\n",					    revision);			} else if (batch) {				fatal("this file doesn't appear to be the "				    "%s version--aborting.\n",				    revision);			} else {				ask("This file doesn't appear to be the "				    "%s version--patch anyway? [n] ",				    revision);				if (*buf != 'y')					fatal("aborted\n");			}		} else if (verbose)			say("Good.  This file appears to be the %s version.\n",			    revision);	}	return true;		/* plan a will work */}