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