/* * --- ROCK-COPYRIGHT-NOTE-BEGIN --- * * This copyright note is auto-generated by ./scripts/Create-CopyPatch. * Please add additional copyright information _after_ the line containing * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by * the ./scripts/Create-CopyPatch script. Do not edit this copyright text! * * ROCK Linux: rock-src/misc/tools-source/cmd_wrapper.c * ROCK Linux is Copyright (C) 1998 - 2006 Clifford Wolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. A copy of the GNU General Public * License can be found at Documentation/COPYING. * * Many people helped and are helping developing ROCK Linux. Please * have a look at https://www.rocklinux.org/ and the Documentation/TEAM * file for details. * * --- ROCK-COPYRIGHT-NOTE-END --- * * Generic command wrapper. * * Recognised Variables: * * prefix_WRAPPER_MYPATH "/path/to/binary" * prefix_WRAPPER_LOGFILE ".cmd_wrapper_log" * * prefix_WRAPPER_DEBUG 0 * prefix_WRAPPER_BYPASS 0 * * prefix_WRAPPER_APPEND_PO "-1st-opt -2nd-opt" * * prefix_WRAPPER_OTHERS "wrapper1:wrapper2:..." * * prefix_WRAPPER_INSERT "-1st-opt -2nd-opt" * prefix_WRAPPER_REMOVE "-del-this-opt -this-also [!-]*" * prefix_WRAPPER_APPEND "-last-opt" * * prefix_WRAPPER_FILTER "sed '...' | awk '...' | foobar" * * prefix_WRAPPER_NOLOOP Internal use only. * */ #include #include #include #include #include #include #include #include #ifndef ENVPREFIX # error You must use -DENVPREFIX=".." when compiling this tool. #endif #ifndef MYNAME # error You must use -DMYNAME=".." when compiling this tool. #endif #define VERBOSE_DEBUG 1 int debug=1; /* * Clean config vars before using them (ugh!) */ void cleanenv(const char * name, const char ch) { int pos1=0, pos2=0, delim=1; char *tmp1, *tmp2; setenv(name, "", 0); tmp1 = getenv(name); tmp2 = malloc(strlen(tmp1)+1); while ( tmp1[pos1] ) { if ( tmp1[pos1] == ch ) { if ( ! delim ) { tmp2[pos2++] = ch; delim = 1; } } else { tmp2[pos2++] = tmp1[pos1]; delim = 0; } pos1++; } if (pos2 > 0 && tmp2[pos2-1] == ch) pos2--; tmp2[pos2] = 0; setenv(name, tmp2, 1); } /* * Main function. */ int main(int argc, char ** argv) { char **newargv; int c1,c2,c3; char *delim, *delim1, *optbuf, *wrdir; FILE *logfile = NULL; /* Calling the wrapper with an absolute path results in an endless-loop. Use basename only to force a $PATH lookup. */ argv[0] = basename(argv[0]); if ( !strcmp(argv[0], MYNAME) ) { if ( argc > 1 ) { argv++; argc--; argv[0] = basename(argv[0]); } else { fprintf(stderr, "Usage: %s command\n", argv[0]); exit(250); } } /* Open logfile (if any) */ delim = getenv(ENVPREFIX "_WRAPPER_LOGFILE"); if (delim && delim[0]) { logfile = fopen(delim, "a"); } if (logfile) { delim = malloc(FILENAME_MAX); if ( getcwd(delim, FILENAME_MAX) == NULL ) delim[0]=0; fprintf(logfile, "\n%s:\n-", delim); for (c3=0; c3_< */ if ( (delim = getenv(ENVPREFIX "_WRAPPER_APPEND_PO_CLEAR")) != NULL ) setenv(ENVPREFIX "_WRAPPER_APPEND_PO", "", 1); /* * Read prefix_WRAPPER_DEBUG and prefix_WRAPPER_BYPASS */ if ( (delim=getenv(ENVPREFIX "_WRAPPER_DEBUG")) != NULL && delim[0] ) debug = atoi(delim); if ( (delim=getenv(ENVPREFIX "_WRAPPER_BYPASS")) != NULL && delim[0] && atoi(delim)) { #if VERBOSE_DEBUG if (debug) fprintf(stderr, "Bypassing cmd_wrapper by " "clearing all config variables.\n"); #endif setenv(ENVPREFIX "_WRAPPER_APPEND_PO", "", 1); setenv(ENVPREFIX "_WRAPPER_OTHERS", "", 1); setenv(ENVPREFIX "_WRAPPER_INSERT", "", 1); setenv(ENVPREFIX "_WRAPPER_REMOVE", "", 1); setenv(ENVPREFIX "_WRAPPER_APPEND", "", 1); setenv(ENVPREFIX "_WRAPPER_FILTER", "", 1); } cleanenv(ENVPREFIX "_WRAPPER_APPEND_PO", ' '); cleanenv(ENVPREFIX "_WRAPPER_OTHERS", ':'); cleanenv(ENVPREFIX "_WRAPPER_INSERT", ' '); cleanenv(ENVPREFIX "_WRAPPER_REMOVE", ' '); cleanenv(ENVPREFIX "_WRAPPER_APPEND", ' '); cleanenv(ENVPREFIX "_WRAPPER_FILTER", '|'); #if VERBOSE_DEBUG if (debug) { fprintf(stderr, "Old Command:"); for (c3=0; c3 abort.\n", newargv[0]); return 250; } /* * Detect loops */ if ( (delim=getenv(ENVPREFIX "_WRAPPER_NOLOOP")) != NULL && delim[0] && delim[0] != '0') { fprintf(stderr, ENVPREFIX "_WRAPPER: Detected loop! -> abort.\n"); return 250; } setenv(ENVPREFIX "_WRAPPER_NOLOOP", "1", 1); /* * Remove the wrapper dir from PATH */ if ( (delim=getenv("PATH")) != NULL && delim[0] && (wrdir=getenv(ENVPREFIX "_WRAPPER_MYPATH")) != NULL && wrdir[0] ) { optbuf = malloc( strlen(delim) + 1 ); optbuf[0] = 0; #if VERBOSE_DEBUG if (debug) fprintf(stderr, "Old PATH: %s\n", delim); #endif delim = strtok(delim, ":"); while ( delim != NULL ) { if (strcmp(delim, wrdir)) { if (optbuf[0]) strcat(optbuf, ":"); strcat(optbuf, delim); } delim = strtok(NULL, ":"); } setenv("PATH", optbuf, 1); #if VERBOSE_DEBUG if (debug) fprintf(stderr, "New PATH: %s\n", optbuf); #endif } else { fprintf(stderr, ENVPREFIX "_WRAPPER: $PATH or $" ENVPREFIX "_WRAPPER_MYPATH is not set! -> abort.\n"); return 250; } /* * Make sure that newargv[] is big enough */ /* start with argc */ c1 = argc; /* add numbers of blanks in prefix_WRAPPER_INSERT */ if ( (delim=getenv(ENVPREFIX "_WRAPPER_INSERT")) != NULL ) while (*delim) { if (*delim==' ') c1++; delim++; } /* add numbers of blanks in prefix_WRAPPER_APPEND */ if ( (delim=getenv(ENVPREFIX "_WRAPPER_APPEND")) != NULL ) while (*delim) { if (*delim==' ') c1++; delim++; } /* add 10 to be sure (3 should be enough) */ newargv=malloc( sizeof(char*) * (c1+10) ); /* init newargv[], c1 and c2 */ newargv[0]=argv[0]; c1=1; c2=1; /* * Copy options from prefix_WRAPPER_INSERT to newargv[] */ if ( (delim=getenv(ENVPREFIX "_WRAPPER_INSERT")) != NULL ) { optbuf = malloc( strlen(delim) + 1 ); strcpy(optbuf, delim); delim = strtok(optbuf, " "); while (delim != NULL) { if (delim[0]) { #if VERBOSE_DEBUG if (debug) fprintf(stderr, "Insert: %s\n", delim); #endif newargv[c1++] = delim; } delim = strtok(NULL, " "); } } /* * Copy options from argv[] to newargv[] if they are not listed * in prefix_WRAPPER_REMOVE */ for (; c2 abort.\n", newargv[0]); return 250; }