/* Copyright 1999-2009 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 */ #include #include #include #include #include #include #define ENVD_CONFIG "/etc/env.d/python/config" int valid_interpreter(const char* name) { /* name must match exactly "pythonX.Y", where the X is between 2 and 9, * and Y is between 0 and 9 */ if (!name || (strcmp(name, "python") == 0) || (strncmp(name, "python", 6) != 0) || strchr(name, '/') || strlen(name) != 9 || name[6] < '2' || name[6] > '9' || name[7] != '.' || name[8] < '0' || name[8] > '9') { return 0; } return 1; } const char* find_latest() { int major = -1; int minor = -1; DIR* d = opendir("/usr/bin"); if (!d) return NULL; struct dirent *entry; while (entry = readdir(d)) { const char* name = entry->d_name; if (valid_interpreter(name)) { int newmajor = name[7]; int newminor = name[9]; /* prefer 2.* to anything later, but otherwise take the latest * version */ if (newmajor == major && newminor > minor || newmajor == '2' && major != '2' || major != '2' && newmajor > major) { major = newmajor; minor = newminor; } } } if (major > 0 && minor > 0) { char pattern[10] = "python0.0"; pattern[7] = major; pattern[9] = minor; char *ret = malloc(10); strncpy(ret, pattern, 10); return ret; } return NULL; } int main(int argc, char** argv) { const char* EPYTHON = getenv("EPYTHON"); if (!valid_interpreter(EPYTHON)) { FILE* f = fopen(ENVD_CONFIG, "r"); if (f) { struct stat st; fstat(fileno(f), &st); size_t size = st.st_size; char* cont = malloc(size + 1); fgets(cont, size + 1, f); fclose(f); size_t len = strlen(cont); if (len && cont[len - 1] == '\n') cont[len - 1] = 0; EPYTHON = cont; } } if (!valid_interpreter(EPYTHON)) EPYTHON = find_latest(); if (!EPYTHON) return 127; execvp(EPYTHON, argv); return 127; }