da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * shell script to shell binary converter
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[-?\n@(#)$Id: shcomp (AT&T Research) 2003-03-02 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?shcomp - compile a shell script]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?Unless \b-D\b is specified, \bshcomp\b takes a shell script, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\ainfile\a, and creates a binary format file, \aoutfile\a, that "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\bksh\b can read and execute with the same effect as the original "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "script.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?Since aliases are processed as the script is read, alias definitions "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "whose value requires variable expansion will not work correctly.]"
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner"[+?If \b-D\b is specified, all double quoted strings that are preceded by "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\b$\b are output. These are the messages that need to be "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "translated to locale specific versions for internationalization.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?If \aoutfile\a is omitted, then the results will be written to "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "standard output. If \ainfile\a is also omitted, the shell script "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "will be read from standard input.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[D:dictionary?Generate a list of strings that need to be placed in a message "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "catalog for internationalization.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[n:noexec?Displays warning messages for obsolete or non-conforming "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "constructs.] "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[v:verbose?Displays input from \ainfile\a onto standard error as it "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "reads it.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n[infile [outfile]]\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+0?Successful completion.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+>0?An error occurred.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bksh\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <shell.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "sys/stat.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CNTL(x) ((x)&037)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define VERSION 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char header[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,VERSION,0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint main(int argc, char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *in, *out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n, nflag=0, vflag=0, dflag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n = optget(argv, usage )) switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dflag=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vflag=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2,"%s",opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp = sh_init(argc,argv,(Shinit_f)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->shcomp = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors || argc>2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp= *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin in = sh_pathopen(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin in = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp= *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(out = sfopen((Sfio_t*)0,cp,"w")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),"%s: cannot create",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fstat(sffileno(out),&statb) >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chmod(cp,(statb.st_mode&~S_IFMT)|S_IXUSR|S_IXGRP|S_IXOTH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = sfstdout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_DICTIONARY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(out,header,sizeof(header));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_BRACEPAT
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_onoption(SH_BRACEEXPAND);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset((char*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t = (Shnode_t*)sh_parse(shp,in,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dflag && sh_tdump(out,t) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),"dump failed");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sfeof(in))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sferror(in))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),"I/O error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t && ((t->tre.tretyp&COMMSK)==TCOM) && (np=t->com.comnamp) && (cp=nv_name(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(cp,"exit")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for exec of a command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(cp,"exec")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->com.comtyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->com.comarg->argnxt.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dolnod *ap = (struct dolnod*)t->com.comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->dolnum>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy any remaining input */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfmove(in,out,SF_UNBOUND,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(in!=sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(in);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(out!=sfstdout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(out);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}