xref: /onnv-gate/usr/src/cmd/fm/eversholt/common/eftwrite.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  *
26*0Sstevel@tonic-gate  * eftwrite.c -- routines for writing .eft files
27*0Sstevel@tonic-gate  *
28*0Sstevel@tonic-gate  * this module emits the table resulting from compilation of the
29*0Sstevel@tonic-gate  * source files.  this code done nothing unless the -o option
30*0Sstevel@tonic-gate  * was given on the command line.
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <string.h>
37*0Sstevel@tonic-gate #include <strings.h>
38*0Sstevel@tonic-gate #include <time.h>
39*0Sstevel@tonic-gate #include <unistd.h>
40*0Sstevel@tonic-gate #include <errno.h>
41*0Sstevel@tonic-gate #include "out.h"
42*0Sstevel@tonic-gate #include "stats.h"
43*0Sstevel@tonic-gate #include "stable.h"
44*0Sstevel@tonic-gate #include "lut.h"
45*0Sstevel@tonic-gate #include "tree.h"
46*0Sstevel@tonic-gate #include "eft.h"
47*0Sstevel@tonic-gate #include "eftwrite.h"
48*0Sstevel@tonic-gate #include "esclex.h"
49*0Sstevel@tonic-gate #include "version.h"
50*0Sstevel@tonic-gate #include "ptree.h"
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate /* for uintX_t, htonl(), etc */
53*0Sstevel@tonic-gate #include <sys/types.h>
54*0Sstevel@tonic-gate #include <netinet/in.h>
55*0Sstevel@tonic-gate #include <inttypes.h>
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate extern char Args[];
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate static struct stats *Outbytes;
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate static int Identlen;
62*0Sstevel@tonic-gate static int Dictlen;
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate void
65*0Sstevel@tonic-gate eftwrite_init(void)
66*0Sstevel@tonic-gate {
67*0Sstevel@tonic-gate 	Outbytes = stats_new_counter("eftwrite.total", "bytes written", 1);
68*0Sstevel@tonic-gate }
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate static const char *
71*0Sstevel@tonic-gate mygetlogin(void)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	const char *result = getlogin();
74*0Sstevel@tonic-gate 	static char id[100];
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	if (result != NULL)
77*0Sstevel@tonic-gate 		return (result);
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate 	(void) snprintf(id, 100, "uid:%ld", getuid());
80*0Sstevel@tonic-gate 	return (id);
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate /*ARGSUSED*/
84*0Sstevel@tonic-gate static void
85*0Sstevel@tonic-gate ident_lencalc(const char *s, void *rhs, void *arg)
86*0Sstevel@tonic-gate {
87*0Sstevel@tonic-gate 	Identlen += strlen(s) + 1;
88*0Sstevel@tonic-gate }
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate /*ARGSUSED*/
91*0Sstevel@tonic-gate static void
92*0Sstevel@tonic-gate dict_lencalc(const char *s, void *rhs, void *arg)
93*0Sstevel@tonic-gate {
94*0Sstevel@tonic-gate 	Dictlen += strlen(s) + 1;
95*0Sstevel@tonic-gate }
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate /*ARGSUSED*/
98*0Sstevel@tonic-gate static void
99*0Sstevel@tonic-gate ident_printer(const char *s, void *rhs, void *arg)
100*0Sstevel@tonic-gate {
101*0Sstevel@tonic-gate 	FILE *fp = (FILE *)arg;
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	fwrite(s, strlen(s) + 1, 1, fp);
104*0Sstevel@tonic-gate }
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate /*ARGSUSED*/
107*0Sstevel@tonic-gate static void
108*0Sstevel@tonic-gate dict_printer(const char *s, void *rhs, void *arg)
109*0Sstevel@tonic-gate {
110*0Sstevel@tonic-gate 	FILE *fp = (FILE *)arg;
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	fwrite(s, strlen(s) + 1, 1, fp);
113*0Sstevel@tonic-gate }
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate void
116*0Sstevel@tonic-gate eftwrite(const char *fname)
117*0Sstevel@tonic-gate {
118*0Sstevel@tonic-gate 	FILE *fp;
119*0Sstevel@tonic-gate 	FILE *tfp;
120*0Sstevel@tonic-gate 	struct eftheader hdr;
121*0Sstevel@tonic-gate #define	BUFLEN	8192
122*0Sstevel@tonic-gate 	char buf[BUFLEN];
123*0Sstevel@tonic-gate 	int cc;
124*0Sstevel@tonic-gate 	time_t clock;
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	if ((tfp = tmpfile()) == NULL)
127*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "cannot create temporary file");
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	/* XXX switch stdout to tfp temporarily */
130*0Sstevel@tonic-gate 	/* XXX for now */
131*0Sstevel@tonic-gate 	out_altfp(tfp);
132*0Sstevel@tonic-gate 	ptree(O_ALTFP, tree_root(NULL), 0, 1);
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	rewind(tfp);
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate 	lut_walk(Ident, (lut_cb)ident_lencalc, (void *)0);
137*0Sstevel@tonic-gate 	lut_walk(Dicts, (lut_cb)dict_lencalc, (void *)0);
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 	bzero(&hdr, sizeof (hdr));
140*0Sstevel@tonic-gate 	hdr.magic = EFT_HDR_MAGIC;
141*0Sstevel@tonic-gate 	hdr.major = EFT_HDR_MAJOR;
142*0Sstevel@tonic-gate 	hdr.minor = EFT_HDR_MINOR;
143*0Sstevel@tonic-gate 	hdr.cmajor = VERSION_MAJOR;
144*0Sstevel@tonic-gate 	hdr.cminor = VERSION_MINOR;
145*0Sstevel@tonic-gate 	hdr.identlen = Identlen;
146*0Sstevel@tonic-gate 	hdr.dictlen = Dictlen;
147*0Sstevel@tonic-gate 	(void) time(&clock);
148*0Sstevel@tonic-gate 	if (gethostname(buf, BUFLEN) < 0)
149*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "gethostname");
150*0Sstevel@tonic-gate 	buf[BUFLEN - 1] = '\0';
151*0Sstevel@tonic-gate 	(void) snprintf(hdr.comment, EFT_HDR_MAXCOMMENT,
152*0Sstevel@tonic-gate 	    "Built using esc-%d.%d by %s on %s at %s\tArgs: \"%s\"\n",
153*0Sstevel@tonic-gate 	    VERSION_MAJOR, VERSION_MINOR, mygetlogin(), buf, ctime(&clock),
154*0Sstevel@tonic-gate 	    Args);
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	if ((fp = fopen(fname, "w")) == NULL)
157*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "can't open output file: %s", fname);
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 	while ((cc = fread(buf, 1, BUFLEN, tfp)) > 0) {
160*0Sstevel@tonic-gate 		char *ptr;
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 		for (ptr = buf; ptr < &buf[cc]; ptr++)
163*0Sstevel@tonic-gate 			hdr.csum += (uint32_t)*ptr;
164*0Sstevel@tonic-gate 	}
165*0Sstevel@tonic-gate 	if (ferror(tfp))
166*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "fread on tmpfile");
167*0Sstevel@tonic-gate 	rewind(tfp);
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	hdr.magic = htonl(hdr.magic);
170*0Sstevel@tonic-gate 	hdr.major = htons(hdr.major);
171*0Sstevel@tonic-gate 	hdr.minor = htons(hdr.minor);
172*0Sstevel@tonic-gate 	hdr.cmajor = htons(hdr.cmajor);
173*0Sstevel@tonic-gate 	hdr.cminor = htons(hdr.cminor);
174*0Sstevel@tonic-gate 	hdr.identlen = htonl(hdr.identlen);
175*0Sstevel@tonic-gate 	hdr.dictlen = htonl(hdr.dictlen);
176*0Sstevel@tonic-gate 	hdr.csum = htonl(hdr.csum);
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	fwrite(&hdr, sizeof (hdr), 1, fp);
179*0Sstevel@tonic-gate 	if (ferror(fp))
180*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "%s: can't write header", fname);
181*0Sstevel@tonic-gate 	stats_counter_add(Outbytes, sizeof (hdr));
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	lut_walk(Ident, (lut_cb)ident_printer, (void *)fp);
184*0Sstevel@tonic-gate 	stats_counter_add(Outbytes, Identlen);
185*0Sstevel@tonic-gate 	lut_walk(Dicts, (lut_cb)dict_printer, (void *)fp);
186*0Sstevel@tonic-gate 	stats_counter_add(Outbytes, Dictlen);
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate 	while ((cc = fread(buf, 1, BUFLEN, tfp)) > 0) {
189*0Sstevel@tonic-gate 		char *ptr;
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 		for (ptr = buf; ptr < &buf[cc]; ptr++)
192*0Sstevel@tonic-gate 			*ptr = ~((unsigned char)*ptr);
193*0Sstevel@tonic-gate 		if (cc != fwrite(buf, 1, cc, fp) || ferror(fp))
194*0Sstevel@tonic-gate 			out(O_DIE|O_SYS, "fwrite on %s", fname);
195*0Sstevel@tonic-gate 		stats_counter_add(Outbytes, cc);
196*0Sstevel@tonic-gate 	}
197*0Sstevel@tonic-gate 	if (ferror(tfp))
198*0Sstevel@tonic-gate 		out(O_DIE|O_SYS, "fread on tmpfile");
199*0Sstevel@tonic-gate 	fclose(tfp);
200*0Sstevel@tonic-gate 	fclose(fp);
201*0Sstevel@tonic-gate }
202