xref: /dragonfly/usr.bin/objformat/objformat.c (revision 4caa7869)
1 /*-
2  * Copyright (c) 1998, Peter Wemm <peter@netplex.com.au>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/usr.bin/objformat/objformat.c,v 1.6 1998/10/24 02:01:30 jdp Exp $
27  * $DragonFly: src/usr.bin/objformat/objformat.c,v 1.3 2004/01/16 07:45:22 dillon Exp $
28  */
29 
30 #include <err.h>
31 #include <objformat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 int
38 main(int argc, char **argv)
39 {
40 	char objformat[32];
41 	char *path, *chunk;
42 	char *cmd, *newcmd = NULL;
43 	char *objformat_path;
44 	char *gccver;
45 	char *dirprefix;
46 	char *dirpostfix;
47 
48 	if (getobjformat(objformat, sizeof objformat, &argc, argv) == -1)
49 		errx(1, "Invalid object format");
50 
51 	/*
52 	 * Get the last path elemenet of the program name being executed
53 	 */
54 	cmd = strrchr(argv[0], '/');
55 	if (cmd != NULL)
56 		cmd++;
57 	else
58 		cmd = argv[0];
59 
60 	/*
61 	 * Directory prefix
62 	 */
63 	if (strcmp(cmd, "c++") == 0 ||
64 		   strcmp(cmd, "cc") == 0 ||
65 		   strcmp(cmd, "cpp") == 0 ||
66 		   strcmp(cmd, "f77") == 0 ||
67 		   strcmp(cmd, "g++") == 0 ||
68 		   strcmp(cmd, "gcc") == 0 ||
69 		   strcmp(cmd, "gcov") == 0
70 	) {
71 		dirprefix = "/usr/bin";
72 		dirpostfix = "";
73 	} else {
74 		dirprefix = "/usr/libexec";
75 		asprintf(&dirpostfix, "/%s", objformat);
76 	}
77 
78 	/*
79 	 * The objformat command itself doesn't need another exec
80 	 */
81 	if (strcmp(cmd, "objformat") == 0) {
82 		if (argc != 1) {
83 			fprintf(stderr, "Usage: objformat\n");
84 			exit(1);
85 		}
86 		printf("%s\n", objformat);
87 		exit(0);
88 	}
89 
90 	/*
91 	 * make buildweorld glue and GCCVER overrides.
92 	 */
93 	objformat_path = getenv("OBJFORMAT_PATH");
94 	if (objformat_path == NULL)
95 		objformat_path = "";
96 	if ((gccver = getenv("GCCVER")) == NULL) {
97 		gccver = "gcc2";
98 	} else if (gccver[0] >= '0' && gccver[0] <= '9') {
99 	    asprintf(&gccver, "gcc%s", gccver);
100 	}
101 	path = strdup(objformat_path);
102 
103 	setenv("OBJFORMAT", objformat, 1);
104 
105 	/*
106 	 * objformat_path could be sequence of colon-separated paths.
107 	 */
108 	while ((chunk = strsep(&path, ":")) != NULL) {
109 		if (newcmd != NULL) {
110 			free(newcmd);
111 			newcmd = NULL;
112 		}
113 		asprintf(&newcmd, "%s%s/%s%s/%s",
114 			chunk, dirprefix, gccver, dirpostfix, cmd);
115 		if (newcmd == NULL)
116 			err(1, "cannot allocate memory");
117 
118 		argv[0] = newcmd;
119 		execv(newcmd, argv);
120 	}
121 	err(1, "in path [%s]%s/%s%s/%s",
122 		objformat_path, dirprefix, gccver, dirpostfix, cmd);
123 }
124 
125