/* * Copyright 1999-2003 Gentoo Technologies, Inc. * Distributed under the terms of the GNU General Public License v2 * Author: Martin Schlemmer * $Header: /home/cvsroot/gentoo-x86/sys-devel/gcc-config/files/wrapper.c,v 1.3 2003/01/15 22:28:10 azarah Exp $ */ #define _REENTRANT #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { FILE *inpipe = NULL; struct stat sbuf; char wrapperbin[MAXPATHLEN + 1], wrapfullname[MAXPATHLEN + 1]; char *wrappername = NULL; char *buffer = NULL, *token = NULL, *tmpstr = NULL, *state = NULL; int ret = 0; char *newargs[argc + 1]; wrapperbin[0] = '\0'; /* What should we find ? */ wrappername = strdupa(basename(argv[0])); /* cc calls gcc ... */ if (0 == strcmp(wrappername, "cc")) sprintf(wrappername, "%s", "gcc"); buffer = (char *) malloc(16); /* Check if we're supposed to use distcc or not... */ sprintf(buffer, "/etc/.usedistcc"); ret = stat(buffer, &sbuf); if ((0 == ret) && (sbuf.st_mode & S_IFREG)) { /* Using distcc, strip the path.. * Assumes that distccd server's are using restricted PATH's */ argv[0] = wrappername; /* Pull in cached gcc-config --get-path-bin from last * source /etc/profile... */ if (buffer) { free(buffer); buffer = NULL; } if (getenv("GCCBINPATH")) { buffer = strdup((char *) getenv("GCCBINPATH")); setenv("PATH", buffer, 1); } else { /* Just get it from gcc-config instead.. printf("Oops! GCCBINPATH not set. Please make sure that you have\n" "the following line in your /etc/profile\n" "[ -f /etc/profile.d/distcc ] && source /etc/profile.d/distcc\n"); exit(1); */ /* GCCBINPATH not set.. get it from gcc-config */ inpipe = popen("/usr/bin/gcc-config --get-bin-path", "r"); if (NULL == inpipe) { fprintf(stderr, "Oops! GCCBINPATH not set and could not run /usr/bin/gcc-config!\n" "Please make sure that you have the following line in your /etc/profile\n" "[ -f /etc/profile.d/distcc ] && source /etc/profile.d/distcc\n"); exit(1); } buffer = (char *)malloc(MAXPATHLEN + 1); if (fgets(buffer, MAXPATHLEN, inpipe) == 0) { fprintf(stderr, "Could not get compiler binary path!\n"); if (buffer) { free(buffer); buffer = NULL; } pclose(inpipe); exit(1); } /* just use wrapfullname to hold path temp */ sscanf(buffer, "%s", wrapfullname); setenv("PATH", wrapfullname, 1); pclose(inpipe); } int j = 1; while (j <= argc) { newargs[j] = argv[j - 1]; j++; } newargs[0] = "/usr/bin/distcc"; /* Ok, do it ... */ if (execv(newargs[0], newargs) < 0) { fprintf(stderr, "Could not run/locate %s!\n", newargs[0]); exit(1); } } else { /* What is the full name of our wrapper? */ snprintf(wrapfullname, strlen("/usr/bin/") + strlen(wrappername) + 1, "%s%s", "/usr/bin/", wrappername); if (buffer) { free(buffer); buffer = NULL; } buffer = strdup((char *) getenv("PATH")); token = strtok_r(buffer, ":", &state); ret = 0; /* Find the first file with suitable name in PATH */ while ((NULL != token) && (strlen(token) > 0)) { tmpstr = (char *) malloc(strlen(token) + strlen(wrappername) + 2); snprintf(tmpstr, strlen(token) + strlen(wrappername) + 2, "%s/%s", token, wrappername); /* Does it exist and is a file? */ ret = stat(tmpstr, &sbuf); /* It exists, and are not our wrapper, and its not in /usr/bin ... */ if ((0 == ret) && (sbuf.st_mode & S_IFREG) && (0 != strcmp(tmpstr, wrapfullname)) && (0 == strstr(tmpstr, "/usr/bin"))) { strncpy(wrapperbin, tmpstr, MAXPATHLEN); if (tmpstr) { free(tmpstr); tmpstr = NULL; } break; } token = strtok_r(NULL, ":", &state); } if (buffer) { free(buffer); buffer = NULL; } /* Did we get a valid binary to execute? */ if (wrapperbin[0] == '\0') { /* It is our wrapper, so get the CC path, and execute the real binary in * there ... */ inpipe = popen("/usr/bin/gcc-config --get-bin-path", "r"); if (NULL == inpipe) { fprintf(stderr, "Could not run /usr/bin/gcc-config!\n"); exit(1); } buffer = (char *)malloc(MAXPATHLEN + 1); if (fgets(buffer, MAXPATHLEN, inpipe) == 0) { fprintf(stderr, "Could not get compiler binary path!\n"); if (buffer) { free(buffer); buffer = NULL; } pclose(inpipe); exit(1); } sscanf(buffer, "%s", wrapperbin); strncat(wrapperbin, "/", MAXPATHLEN - strlen(wrapperbin)); strncat(wrapperbin, wrappername, MAXPATHLEN - strlen(wrapperbin)); pclose(inpipe); if (buffer) { free(buffer); buffer = NULL; } } /* Set argv[0] to the correct binary, else gcc do not find internal * headers, etc (bug #8132). */ argv[0] = wrapperbin; /* Ok, do it ... */ if (execv(argv[0], argv) < 0) { fprintf(stderr, "Could not run/locate %s!\n", argv[0]); exit(1); } } return 0; }