cmdexec.c revision 9781:ccf49524d5dc
1353944Sdim/*
2353944Sdim * CDDL HEADER START
3353944Sdim *
4353944Sdim * The contents of this file are subject to the terms of the
5353944Sdim * Common Development and Distribution License (the "License").
6353944Sdim * You may not use this file except in compliance with the License.
7353944Sdim *
8353944Sdim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9353944Sdim * or http://www.opensolaris.org/os/licensing.
10353944Sdim * See the License for the specific language governing permissions
11353944Sdim * and limitations under the License.
12353944Sdim *
13353944Sdim * When distributing Covered Code, include this CDDL HEADER in each
14353944Sdim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15353944Sdim * If applicable, add the following below this CDDL HEADER, with the
16353944Sdim * fields enclosed by brackets "[]" replaced with your own identifying
17353944Sdim * information: Portions Copyright [yyyy] [name of copyright owner]
18353944Sdim *
19353944Sdim * CDDL HEADER END
20353944Sdim */
21353944Sdim
22353944Sdim/*
23353944Sdim * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24353944Sdim * Use is subject to license terms.
25353944Sdim */
26353944Sdim
27353944Sdim/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28353944Sdim/* All Rights Reserved */
29353944Sdim
30353944Sdim
31353944Sdim#include <stdio.h>
32353944Sdim#include <ctype.h>
33353944Sdim#include <string.h>
34353944Sdim#include <locale.h>
35353944Sdim#include <libintl.h>
36353944Sdim#include <stdlib.h>
37353944Sdim#include <unistd.h>
38353944Sdim#include <pkglib.h>
39353944Sdim
40353944Sdim#define	COMMAND '!'
41353944Sdim#define	LSIZE 256
42353944Sdim
43353944Sdim#define	ERR_NOTROOT	"You must be \"root\" for %s to execute properly."
44353944Sdim
45353944Sdimstatic void	usage(void);
46353944Sdimstatic int	docmd(char *cmd, char *file, char *input);
47353944Sdim
48353944Sdimint
49353944Sdimmain(int argc, char *argv[])
50353944Sdim{
51353944Sdim	FILE	*fpout, *fp;
52353944Sdim	char	line[LSIZE],
53353944Sdim		*pt,
54353944Sdim		*keyword, 	/* keyword = install || remove */
55353944Sdim		*input, 	/* sed input file */
56353944Sdim		*cmd,
57353944Sdim		*srcfile, 	/* sed data file */
58353944Sdim		*destfile; 	/* target file to be updated */
59353944Sdim	int	flag;
60353944Sdim	char	*prog;
61353944Sdim
62353944Sdim	(void) setlocale(LC_ALL, "");
63353944Sdim
64353944Sdim#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
65353944Sdim#define	TEXT_DOMAIN "SYS_TEST"
66353944Sdim#endif
67353944Sdim	(void) textdomain(TEXT_DOMAIN);
68353944Sdim
69353944Sdim	prog = set_prog_name(argv[0]);
70353944Sdim
71353944Sdim	if (getuid()) {
72353944Sdim		progerr(gettext(ERR_NOTROOT), prog);
73353944Sdim		exit(1);
74353944Sdim	}
75353944Sdim
76353944Sdim	if (argc != 5)
77353944Sdim		usage();
78353944Sdim
79353944Sdim	cmd = argv[1];
80353944Sdim	keyword = argv[2];
81353944Sdim	srcfile = argv[3];
82353944Sdim	destfile = argv[4];
83353944Sdim
84353944Sdim	srcfile = argv[3];
85353944Sdim	if ((fp = fopen(srcfile, "r")) == NULL) {
86353944Sdim		progerr(gettext("unable to open %s"), srcfile);
87353944Sdim		exit(1);
88353944Sdim	}
89353944Sdim
90353944Sdim	input = tempnam(NULL, "sedinp");
91353944Sdim	if ((fpout = fopen(input, "w")) == NULL) {
92353944Sdim		progerr(gettext("unable to open %s"), input);
93353944Sdim		exit(2);
94353944Sdim	}
95353944Sdim
96353944Sdim	flag = (-1);
97353944Sdim	while (fgets(line, LSIZE, fp)) {
98353944Sdim		for (pt = line; isspace(*pt); /* void */)
99353944Sdim			++pt;
100353944Sdim		if (*pt == '#')
101353944Sdim			continue;
102353944Sdim		if (*pt == COMMAND) {
103353944Sdim			if (flag > 0)
104353944Sdim				break; /* no more lines to read */
105353944Sdim			pt = strtok(pt+1, " \t\n");
106353944Sdim			if (!pt) {
107353944Sdim				progerr(gettext("null token after '!'"));
108353944Sdim				exit(1);
109353944Sdim			}
110353944Sdim			flag = (strcmp(pt, keyword) ? 0 : 1);
111353944Sdim		} else if (flag == 1) { /* bug # 1083359 */
112353944Sdim			(void) fputs(line, fpout);
113353944Sdim		}
114353944Sdim	}
115353944Sdim	(void) fclose(fpout);
116357095Sdim	if (flag > 0) {
117357095Sdim		if (docmd(cmd, destfile, input)) {
118357095Sdim			progerr(gettext("command failed <%s>"), cmd);
119353944Sdim			exit(1);
120353944Sdim		}
121353944Sdim	}
122357095Sdim	(void) unlink(input);
123357095Sdim	return (0);
124357095Sdim}
125357095Sdim
126353944Sdimstatic int
127353944Sdimdocmd(char *cmd, char *file, char *input)
128353944Sdim{
129353944Sdim	char *tempout;
130353944Sdim	char command[256];
131353944Sdim
132353944Sdim	tempout = tempnam(NULL, "temp1");
133353944Sdim	if (!tempout)
134353944Sdim		return (-1);
135353944Sdim
136353944Sdim	(void) sprintf(command, "%s -f %s <%s >%s", cmd, input, file, tempout);
137353944Sdim	if (system(command))
138353944Sdim		return (-1);
139353944Sdim
140353944Sdim	(void) sprintf(command, "cp %s %s", tempout, file);
141353944Sdim	if (system(command))
142353944Sdim		return (-1);
143353944Sdim
144353944Sdim	(void) unlink(tempout);
145353944Sdim	free(tempout);
146353944Sdim	return (0);
147353944Sdim}
148353944Sdim
149353944Sdimstatic void
150353944Sdimusage(void)
151353944Sdim{
152353944Sdim	(void) fprintf(stderr, gettext("usage: %s cmd keyword src dest\n"),
153353944Sdim	    get_prog_name());
154353944Sdim	exit(2);
155353944Sdim}
156353944Sdim