xref: /dflybsd-src/contrib/nvi2/ex/ex_source.c (revision 07bc39c2f4bbca56f12568e06d89da17f2eeb965)
1e0b8e63eSJohn Marino /*-
2e0b8e63eSJohn Marino  * Copyright (c) 1992, 1993, 1994
3e0b8e63eSJohn Marino  *	The Regents of the University of California.  All rights reserved.
4e0b8e63eSJohn Marino  * Copyright (c) 1992, 1993, 1994, 1995, 1996
5e0b8e63eSJohn Marino  *	Keith Bostic.  All rights reserved.
6e0b8e63eSJohn Marino  *
7e0b8e63eSJohn Marino  * See the LICENSE file for redistribution information.
8e0b8e63eSJohn Marino  */
9e0b8e63eSJohn Marino 
10e0b8e63eSJohn Marino #include "config.h"
11e0b8e63eSJohn Marino 
12e0b8e63eSJohn Marino #include <sys/types.h>
13e0b8e63eSJohn Marino #include <sys/queue.h>
14e0b8e63eSJohn Marino #include <sys/stat.h>
15e0b8e63eSJohn Marino 
16e0b8e63eSJohn Marino #include <bitstring.h>
17e0b8e63eSJohn Marino #include <errno.h>
18e0b8e63eSJohn Marino #include <fcntl.h>
19e0b8e63eSJohn Marino #include <limits.h>
20e0b8e63eSJohn Marino #include <stdio.h>
21e0b8e63eSJohn Marino #include <stdlib.h>
22e0b8e63eSJohn Marino #include <string.h>
23e0b8e63eSJohn Marino #include <unistd.h>
24e0b8e63eSJohn Marino 
25e0b8e63eSJohn Marino #include "../common/common.h"
26e0b8e63eSJohn Marino 
27e0b8e63eSJohn Marino /*
28e0b8e63eSJohn Marino  * ex_source -- :source file
29e0b8e63eSJohn Marino  *	Execute ex commands from a file.
30e0b8e63eSJohn Marino  *
31e0b8e63eSJohn Marino  * PUBLIC: int ex_source(SCR *, EXCMD *);
32e0b8e63eSJohn Marino  */
33e0b8e63eSJohn Marino int
ex_source(SCR * sp,EXCMD * cmdp)34e0b8e63eSJohn Marino ex_source(SCR *sp, EXCMD *cmdp)
35e0b8e63eSJohn Marino {
36e0b8e63eSJohn Marino 	struct stat sb;
37e0b8e63eSJohn Marino 	int fd, len;
38e0b8e63eSJohn Marino 	char *bp;
39e0b8e63eSJohn Marino 	char *name, *np;
40e0b8e63eSJohn Marino 	size_t nlen;
41e0b8e63eSJohn Marino 	CHAR_T *wp;
42e0b8e63eSJohn Marino 	size_t wlen;
43e0b8e63eSJohn Marino 	int rc;
44e0b8e63eSJohn Marino 
45e0b8e63eSJohn Marino 	INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, name, nlen);
46e0b8e63eSJohn Marino 	if ((fd = open(name, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
47e0b8e63eSJohn Marino 		goto err;
48e0b8e63eSJohn Marino 
49e0b8e63eSJohn Marino 	/*
50e0b8e63eSJohn Marino 	 * XXX
51e0b8e63eSJohn Marino 	 * I'd like to test to see if the file is too large to malloc.  Since
52e0b8e63eSJohn Marino 	 * we don't know what size or type off_t's or size_t's are, what the
53e0b8e63eSJohn Marino 	 * largest unsigned integral type is, or what random insanity the local
54e0b8e63eSJohn Marino 	 * C compiler will perpetrate, doing the comparison in a portable way
55e0b8e63eSJohn Marino 	 * is flatly impossible.  So, put an fairly unreasonable limit on it,
56e0b8e63eSJohn Marino 	 * I don't want to be dropping core here.
57e0b8e63eSJohn Marino 	 */
58e0b8e63eSJohn Marino #define	MEGABYTE	1048576
59e0b8e63eSJohn Marino 	if (sb.st_size > MEGABYTE) {
60e0b8e63eSJohn Marino 		errno = ENOMEM;
61e0b8e63eSJohn Marino 		goto err;
62e0b8e63eSJohn Marino 	}
63e0b8e63eSJohn Marino 
64*b1ac2ebbSDaniel Fojt 	MALLOC(sp, bp, (size_t)sb.st_size + 1);
65e0b8e63eSJohn Marino 	if (bp == NULL) {
66e0b8e63eSJohn Marino 		(void)close(fd);
67e0b8e63eSJohn Marino 		return (1);
68e0b8e63eSJohn Marino 	}
69e0b8e63eSJohn Marino 	bp[sb.st_size] = '\0';
70e0b8e63eSJohn Marino 
71e0b8e63eSJohn Marino 	/* Read the file into memory. */
72e0b8e63eSJohn Marino 	len = read(fd, bp, (int)sb.st_size);
73e0b8e63eSJohn Marino 	(void)close(fd);
74e0b8e63eSJohn Marino 	if (len == -1 || len != sb.st_size) {
75e0b8e63eSJohn Marino 		if (len != sb.st_size)
76e0b8e63eSJohn Marino 			errno = EIO;
77e0b8e63eSJohn Marino 		free(bp);
78e0b8e63eSJohn Marino err:		msgq_str(sp, M_SYSERR, name, "%s");
79e0b8e63eSJohn Marino 		return (1);
80e0b8e63eSJohn Marino 	}
81e0b8e63eSJohn Marino 
82e0b8e63eSJohn Marino 	np = strdup(name);
83e0b8e63eSJohn Marino 	if (CHAR2INT(sp, bp, (size_t)sb.st_size + 1, wp, wlen))
84e0b8e63eSJohn Marino 		msgq(sp, M_ERR, "323|Invalid input. Truncated.");
85e0b8e63eSJohn Marino 	/* Put it on the ex queue. */
86e0b8e63eSJohn Marino 	rc = ex_run_str(sp, np, wp, wlen - 1, 1, 0);
87e0b8e63eSJohn Marino 	free(np);
88e0b8e63eSJohn Marino 	free(bp);
89e0b8e63eSJohn Marino 	return (rc);
90e0b8e63eSJohn Marino }
91