xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/sh/shcomp.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  * David Korn
23*b30d1939SAndy Fiddaman  * AT&T Labs
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  * shell script to shell binary converter
26*b30d1939SAndy Fiddaman  *
27*b30d1939SAndy Fiddaman  */
28*b30d1939SAndy Fiddaman 
29*b30d1939SAndy Fiddaman static const char usage[] =
30*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: shcomp (AT&T Research) 2003-03-02 $\n]"
31*b30d1939SAndy Fiddaman USAGE_LICENSE
32*b30d1939SAndy Fiddaman "[+NAME?shcomp - compile a shell script]"
33*b30d1939SAndy Fiddaman "[+DESCRIPTION?Unless \b-D\b is specified, \bshcomp\b takes a shell script, "
34*b30d1939SAndy Fiddaman 	"\ainfile\a, and creates a binary format file, \aoutfile\a, that "
35*b30d1939SAndy Fiddaman 	"\bksh\b can read and execute with the same effect as the original "
36*b30d1939SAndy Fiddaman 	"script.]"
37*b30d1939SAndy Fiddaman "[+?Since aliases are processed as the script is read, alias definitions "
38*b30d1939SAndy Fiddaman 	"whose value requires variable expansion will not work correctly.]"
39*b30d1939SAndy Fiddaman "[+?If \b-D\b is specified, all double quoted strings that are preceded by "
40*b30d1939SAndy Fiddaman 	"\b$\b are output.  These are the messages that need to be "
41*b30d1939SAndy Fiddaman 	"translated to locale specific versions for internationalization.]"
42*b30d1939SAndy Fiddaman "[+?If \aoutfile\a is omitted, then the results will be written to "
43*b30d1939SAndy Fiddaman 	"standard output.  If \ainfile\a is also omitted, the shell script "
44*b30d1939SAndy Fiddaman 	"will be read from standard input.]"
45*b30d1939SAndy Fiddaman "[D:dictionary?Generate a list of strings that need to be placed in a message "
46*b30d1939SAndy Fiddaman 	"catalog for internationalization.]"
47*b30d1939SAndy Fiddaman "[n:noexec?Displays warning messages for obsolete or non-conforming "
48*b30d1939SAndy Fiddaman 	"constructs.] "
49*b30d1939SAndy Fiddaman "[v:verbose?Displays input from \ainfile\a onto standard error as it "
50*b30d1939SAndy Fiddaman 	"reads it.]"
51*b30d1939SAndy Fiddaman "\n"
52*b30d1939SAndy Fiddaman "\n[infile [outfile]]\n"
53*b30d1939SAndy Fiddaman "\n"
54*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
55*b30d1939SAndy Fiddaman         "[+0?Successful completion.]"
56*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
57*b30d1939SAndy Fiddaman "}"
58*b30d1939SAndy Fiddaman "[+SEE ALSO?\bksh\b(1)]"
59*b30d1939SAndy Fiddaman ;
60*b30d1939SAndy Fiddaman 
61*b30d1939SAndy Fiddaman #include	<shell.h>
62*b30d1939SAndy Fiddaman #include	"defs.h"
63*b30d1939SAndy Fiddaman #include	"shnodes.h"
64*b30d1939SAndy Fiddaman #include	"sys/stat.h"
65*b30d1939SAndy Fiddaman 
66*b30d1939SAndy Fiddaman #define CNTL(x)	((x)&037)
67*b30d1939SAndy Fiddaman #define VERSION	3
68*b30d1939SAndy Fiddaman static const char header[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,VERSION,0 };
69*b30d1939SAndy Fiddaman 
main(int argc,char * argv[])70*b30d1939SAndy Fiddaman int main(int argc, char *argv[])
71*b30d1939SAndy Fiddaman {
72*b30d1939SAndy Fiddaman 	Sfio_t *in, *out;
73*b30d1939SAndy Fiddaman 	Shell_t	*shp;
74*b30d1939SAndy Fiddaman 	Namval_t *np;
75*b30d1939SAndy Fiddaman 	Shnode_t *t;
76*b30d1939SAndy Fiddaman 	char *cp;
77*b30d1939SAndy Fiddaman 	int n, nflag=0, vflag=0, dflag=0;
78*b30d1939SAndy Fiddaman 	error_info.id = argv[0];
79*b30d1939SAndy Fiddaman 	while(n = optget(argv, usage )) switch(n)
80*b30d1939SAndy Fiddaman 	{
81*b30d1939SAndy Fiddaman 	    case 'D':
82*b30d1939SAndy Fiddaman 		dflag=1;
83*b30d1939SAndy Fiddaman 		break;
84*b30d1939SAndy Fiddaman 	    case 'v':
85*b30d1939SAndy Fiddaman 		vflag=1;
86*b30d1939SAndy Fiddaman 		break;
87*b30d1939SAndy Fiddaman 	    case 'n':
88*b30d1939SAndy Fiddaman 		nflag=1;
89*b30d1939SAndy Fiddaman 		break;
90*b30d1939SAndy Fiddaman 	    case ':':
91*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,2,"%s",opt_info.arg);
92*b30d1939SAndy Fiddaman 		break;
93*b30d1939SAndy Fiddaman 	    case '?':
94*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
95*b30d1939SAndy Fiddaman 		break;
96*b30d1939SAndy Fiddaman 	}
97*b30d1939SAndy Fiddaman 	shp = sh_init(argc,argv,(Shinit_f)0);
98*b30d1939SAndy Fiddaman 	shp->shcomp = 1;
99*b30d1939SAndy Fiddaman 	argv += opt_info.index;
100*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
101*b30d1939SAndy Fiddaman 	if(error_info.errors || argc>2)
102*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
103*b30d1939SAndy Fiddaman 	if(cp= *argv)
104*b30d1939SAndy Fiddaman 	{
105*b30d1939SAndy Fiddaman 		argv++;
106*b30d1939SAndy Fiddaman 		in = sh_pathopen(cp);
107*b30d1939SAndy Fiddaman 	}
108*b30d1939SAndy Fiddaman 	else
109*b30d1939SAndy Fiddaman 		in = sfstdin;
110*b30d1939SAndy Fiddaman 	if(cp= *argv)
111*b30d1939SAndy Fiddaman 	{
112*b30d1939SAndy Fiddaman 		struct stat statb;
113*b30d1939SAndy Fiddaman 		if(!(out = sfopen((Sfio_t*)0,cp,"w")))
114*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_system(1),"%s: cannot create",cp);
115*b30d1939SAndy Fiddaman 		if(fstat(sffileno(out),&statb) >=0)
116*b30d1939SAndy Fiddaman 			chmod(cp,(statb.st_mode&~S_IFMT)|S_IXUSR|S_IXGRP|S_IXOTH);
117*b30d1939SAndy Fiddaman 	}
118*b30d1939SAndy Fiddaman 	else
119*b30d1939SAndy Fiddaman 		out = sfstdout;
120*b30d1939SAndy Fiddaman 	if(dflag)
121*b30d1939SAndy Fiddaman 	{
122*b30d1939SAndy Fiddaman 		sh_onoption(SH_DICTIONARY);
123*b30d1939SAndy Fiddaman 		sh_onoption(SH_NOEXEC);
124*b30d1939SAndy Fiddaman 	}
125*b30d1939SAndy Fiddaman 	if(nflag)
126*b30d1939SAndy Fiddaman 		sh_onoption(SH_NOEXEC);
127*b30d1939SAndy Fiddaman 	if(vflag)
128*b30d1939SAndy Fiddaman 		sh_onoption(SH_VERBOSE);
129*b30d1939SAndy Fiddaman 	if(!dflag)
130*b30d1939SAndy Fiddaman 		sfwrite(out,header,sizeof(header));
131*b30d1939SAndy Fiddaman 	shp->inlineno = 1;
132*b30d1939SAndy Fiddaman #if SHOPT_BRACEPAT
133*b30d1939SAndy Fiddaman         sh_onoption(SH_BRACEEXPAND);
134*b30d1939SAndy Fiddaman #endif
135*b30d1939SAndy Fiddaman 	while(1)
136*b30d1939SAndy Fiddaman 	{
137*b30d1939SAndy Fiddaman 		stakset((char*)0,0);
138*b30d1939SAndy Fiddaman 		if(t = (Shnode_t*)sh_parse(shp,in,0))
139*b30d1939SAndy Fiddaman 		{
140*b30d1939SAndy Fiddaman 			if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
141*b30d1939SAndy Fiddaman 				sh_exec(t,0);
142*b30d1939SAndy Fiddaman 			if(!dflag && sh_tdump(out,t) < 0)
143*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,ERROR_exit(1),"dump failed");
144*b30d1939SAndy Fiddaman 		}
145*b30d1939SAndy Fiddaman 		else if(sfeof(in))
146*b30d1939SAndy Fiddaman 			break;
147*b30d1939SAndy Fiddaman 		if(sferror(in))
148*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_system(1),"I/O error");
149*b30d1939SAndy Fiddaman 		if(t && ((t->tre.tretyp&COMMSK)==TCOM) && (np=t->com.comnamp) && (cp=nv_name(np)))
150*b30d1939SAndy Fiddaman 		{
151*b30d1939SAndy Fiddaman 			if(strcmp(cp,"exit")==0)
152*b30d1939SAndy Fiddaman 				break;
153*b30d1939SAndy Fiddaman 			/* check for exec of a command */
154*b30d1939SAndy Fiddaman 			if(strcmp(cp,"exec")==0)
155*b30d1939SAndy Fiddaman 			{
156*b30d1939SAndy Fiddaman 				if(t->com.comtyp&COMSCAN)
157*b30d1939SAndy Fiddaman 				{
158*b30d1939SAndy Fiddaman 					if(t->com.comarg->argnxt.ap)
159*b30d1939SAndy Fiddaman 						break;
160*b30d1939SAndy Fiddaman 				}
161*b30d1939SAndy Fiddaman 				else
162*b30d1939SAndy Fiddaman 				{
163*b30d1939SAndy Fiddaman 					struct dolnod *ap = (struct dolnod*)t->com.comarg;
164*b30d1939SAndy Fiddaman 					if(ap->dolnum>1)
165*b30d1939SAndy Fiddaman 						break;
166*b30d1939SAndy Fiddaman 				}
167*b30d1939SAndy Fiddaman 			}
168*b30d1939SAndy Fiddaman 		}
169*b30d1939SAndy Fiddaman 	}
170*b30d1939SAndy Fiddaman 	/* copy any remaining input */
171*b30d1939SAndy Fiddaman 	sfmove(in,out,SF_UNBOUND,-1);
172*b30d1939SAndy Fiddaman 	if(in!=sfstdin)
173*b30d1939SAndy Fiddaman 		sfclose(in);
174*b30d1939SAndy Fiddaman 	if(out!=sfstdout)
175*b30d1939SAndy Fiddaman 		sfclose(out);
176*b30d1939SAndy Fiddaman 	return(0);
177*b30d1939SAndy Fiddaman }
178