8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / mcs / common / main.c
blob03410bf26ce23bd2221f7041afde58dc9bd4109c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 1988 AT&T
26 * All Rights Reserved
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
30 * Use is subject to license terms.
33 #include "stdlib.h"
34 #include "conv.h"
35 #include "mcs.h"
36 #include "extern.h"
37 #define OPTUNIT 100
39 static size_t optcnt = 0;
40 static size_t optbufsz = OPTUNIT;
43 * Function prototypes.
45 static void usage(int);
46 static void sigexit(int);
47 static int setup_sectname(char *, int);
48 static void queue(int, char *);
50 int
51 main(int argc, char ** argv, char ** envp)
53 const char *opt;
54 char *str;
55 int error_count = 0, num_sect = 0, errflag = 0;
56 int c, i, my_prog;
57 Cmd_Info *cmd_info;
60 * Check for a binary that better fits this architecture.
62 (void) conv_check_native(argv, envp);
65 * mcs(1) and strip() are hard linked together, determine which command
66 * was invoked.
68 prog = argv[0];
69 if ((str = strrchr(prog, '/')) != NULL)
70 str++;
71 else
72 str = prog;
74 if (strcmp(str, "mcs") == 0) {
75 my_prog = MCS;
76 opt = "a:cdn:pVz?";
77 } else if (strcmp(str, "strip") == 0) {
78 my_prog = STRIP;
79 opt = "lxV?";
80 } else
81 exit(FAILURE);
83 (void) setlocale(LC_ALL, "");
84 #if !defined(TEXT_DOMAIN)
85 #define TEXT_DOMAIN "SYS_TEST"
86 #endif
87 (void) textdomain(TEXT_DOMAIN);
89 for (i = 0; signum[i]; i++)
90 if (signal(signum[i], SIG_IGN) != SIG_IGN)
91 (void) signal(signum[i], sigexit);
93 if ((Action =
94 malloc(optbufsz * sizeof (struct action))) == NULL) {
95 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
96 exit(FAILURE);
100 * Allocate command info structure
102 cmd_info = (Cmd_Info *) calloc(1, sizeof (Cmd_Info));
103 if (cmd_info == NULL) {
104 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
105 exit(FAILURE);
107 if (my_prog == STRIP)
108 cmd_info->flags |= I_AM_STRIP;
110 while ((c = getopt(argc, argv, (char *)opt)) != EOF) {
111 switch (c) {
112 case 'a':
113 optcnt++;
114 queue(ACT_APPEND, optarg);
115 cmd_info->flags |= (MIGHT_CHG | aFLAG);
116 cmd_info->str_size += strlen(optarg) + 1;
117 break;
118 case 'c':
119 optcnt++;
120 queue(ACT_COMPRESS, NULL);
121 cmd_info->flags |= (MIGHT_CHG | cFLAG);
122 break;
123 case 'd':
124 optcnt++;
125 if (CHK_OPT(cmd_info, dFLAG) == 0)
126 queue(ACT_DELETE, NULL);
127 cmd_info->flags |= (MIGHT_CHG | dFLAG);
128 break;
129 case 'z':
130 optcnt++;
131 queue(ACT_ZAP, NULL);
132 cmd_info->flags |= (MIGHT_CHG | zFLAG);
133 break;
134 case 'n':
135 (void) setup_sectname(optarg, my_prog);
136 num_sect++;
137 break;
138 case 'l':
139 optcnt++;
140 cmd_info->flags |= lFLAG;
141 break;
142 case 'p':
143 optcnt++;
144 queue(ACT_PRINT, NULL);
145 cmd_info->flags |= pFLAG;
146 break;
147 case 'x':
148 optcnt++;
149 cmd_info->flags |= xFLAG;
150 break;
151 case 'V':
152 cmd_info->flags |= VFLAG;
153 (void) fprintf(stderr, "%s: %s %s\n", prog,
154 (const char *)SGU_PKG, (const char *)SGU_REL);
155 break;
156 case '?':
157 errflag++;
158 break;
159 default:
160 break;
164 if (errflag) {
165 usage(my_prog);
166 exit(FAILURE);
170 * strip command may not take any options.
172 if (my_prog != STRIP) {
173 if (argc == optind &&
174 (CHK_OPT(cmd_info, MIGHT_CHG) || CHK_OPT(cmd_info, pFLAG) ||
175 argc == 1))
176 usage(my_prog);
177 else if (!CHK_OPT(cmd_info, MIGHT_CHG) &&
178 !CHK_OPT(cmd_info, pFLAG) && !CHK_OPT(cmd_info, VFLAG))
179 usage(my_prog);
183 * This version only allows multiple section names
184 * only for -d option.
186 if ((num_sect >= 2) && (CHK_OPT(cmd_info, pFLAG) ||
187 CHK_OPT(cmd_info, aFLAG) ||
188 CHK_OPT(cmd_info, cFLAG))) {
189 error_message(USAGE_ERROR, PLAIN_ERROR, (char *)0, prog);
190 exit(FAILURE);
194 * If no -n was specified,
195 * set the default, ".comment".
196 * This is for mcs only.
198 if (num_sect == 0 && my_prog == MCS) {
199 (void) setup_sectname(".comment", MCS);
203 * If I am strip command, then add needed
204 * section names.
206 if (my_prog == STRIP) {
207 (void) setup_sectname(".line", MCS);
208 if (CHK_OPT(cmd_info, lFLAG) == 0) {
209 (void) setup_sectname(".debug", STRIP);
210 (void) setup_sectname(".stab", STRIP);
212 if (CHK_OPT(cmd_info, dFLAG) == 0) {
213 queue(ACT_DELETE, NULL);
214 cmd_info->flags |= MIGHT_CHG;
215 cmd_info->flags |= dFLAG;
219 (void) elf_version(EV_NONE);
220 if (elf_version(EV_CURRENT) == EV_NONE) {
221 error_message(ELFVER_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
222 exit(FAILURE);
225 if (CHK_OPT(cmd_info, pFLAG) || CHK_OPT(cmd_info, MIGHT_CHG)) {
226 for (; optind < argc; optind++) {
227 error_count = error_count +
228 (each_file(argv[optind], cmd_info));
232 mcs_exit(error_count);
233 /*NOTREACHED*/
234 return (0);
238 * Supplementary functions
240 static void
241 queue(int activity, char *string)
243 if (optcnt > optbufsz) {
244 optbufsz = optbufsz * 2;
245 if ((Action = realloc((struct action *)Action,
246 optbufsz * sizeof (struct action))) == NULL) {
247 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
248 mcs_exit(FAILURE);
251 Action[actmax].a_action = activity;
252 Action[actmax].a_cnt = 0;
253 Action[actmax].a_string = string;
254 actmax++;
258 * Reset a temporary file descriptor for reuse.
259 * If the file requires unlinking, that is done first.
261 void
262 free_tempfile(Tmp_File *temp_file)
264 if ((temp_file->tmp_name != NULL) && (temp_file->tmp_unlink))
265 (void) unlink(temp_file->tmp_name);
266 (void) memset(temp_file, 0, sizeof (*temp_file));
269 /*ARGSUSED0*/
270 static void
271 sigexit(int i)
273 free_tempfile(&artmpfile);
274 free_tempfile(&elftmpfile);
275 exit(100);
278 static void
279 usage(int me)
281 if (me == MCS)
282 (void) fprintf(stderr, gettext(
283 "usage: %s [-cdpVz] [-a string] [-n name] file ...\n"), prog);
284 else
285 (void) fprintf(stderr, gettext(
286 "usage: %s [-lVx] file ...\n"), prog);
287 mcs_exit(FAILURE);
290 void
291 mcs_exit(int val)
293 free_tempfile(&artmpfile);
294 free_tempfile(&elftmpfile);
295 exit(val);
299 * Insert the section name 'name' into the
300 * section list.
302 static int
303 setup_sectname(char *name, int whoami)
305 S_Name *new;
308 * Check if the name is already specified or not.
310 if ((whoami == MCS) && (sectcmp(name) == 0))
311 return (0);
314 * Allocate one
316 if ((new = malloc(sizeof (S_Name))) == NULL) {
317 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
318 exit(FAILURE);
320 new->name = strdup(name);
321 if (new->name == NULL) {
322 error_message(USAGE_ERROR, PLAIN_ERROR, (char *)0, prog);
323 exit(FAILURE);
325 if (whoami == STRIP)
326 new->flags = SNAME_FLG_STRNCMP;
327 new->next = NULL;
330 * Put this one in the list
332 new->next = sect_head;
333 sect_head = new;
335 return (0);
339 * Check if the 'name' exists in the section list.
341 * If found
342 * return 0;
343 * else
344 * return 1
347 sectcmp(char *name)
350 * Check if the name is already specified or not.
352 if (sect_head != NULL) {
353 S_Name *p1 = sect_head;
354 while (p1 != NULL) {
355 if (p1->flags & SNAME_FLG_STRNCMP) {
356 if (strncmp(p1->name,
357 name, strlen(p1->name)) == 0)
358 return (0);
359 } else if (strcmp(p1->name, name) == 0) {
360 return (0); /* silently ignore */
362 p1 = p1->next;
365 return (1);