/* Copyright (C) 1994, Klaus Preschern. */ /* All rights reserved. */ /* See the file COPYRIGHT.KP for a full description. */ #include #include #include #include #include #define DEBUG 0 #define PATH_LEN 1024 #define QUAKE_LEN 1024 #define UNIT_LEN 1024 static char quake [] = "/ex32/usr/local/bin/quake"; static char template_dir [PATH_LEN] = "/ex32/usr/local/lib/m3/pkg/m3build/templates"; static char template [PATH_LEN] = "DOS"; static char build_dir [PATH_LEN] = "DOS"; static char start_dir [PATH_LEN] = "."; static char quake_args [QUAKE_LEN] = ""; static char units [UNIT_LEN] = ""; static char show_hidden [12] = ""; static char verbose [2] = "n"; static char base [PATH_LEN] = ""; static char parent [PATH_LEN] = ""; static char tmp [PATH_LEN] = ""; static char basetmp [PATH_LEN] = ""; static char package_dir [PATH_LEN] = ""; static char package [PATH_LEN] = ""; static char query [PATH_LEN] = "/ex32/tmp/m3find.$$"; static char unit [PATH_LEN] = ""; static int is_dir (char * name) { struct stat statbuf; #if DEBUG printf ("is_dir (%s)\n", name); #endif if (stat (name, &statbuf) < 0) { return 0; } return (statbuf.st_mode & __S_IFDIR); } static int readable (char * name) { /* we do not check for readability, just for existence */ struct stat statbuf; #if DEBUG printf ("readable (%s)\n", name); #endif return (!(stat (name, &statbuf) < 0)); } static char * dircat (char * dir1, char * dir2) { char tmp1 [PATH_LEN], tmp2 [PATH_LEN]; /* 'dir1' or 'dir2' could be 'tmp' */ strcpy (tmp1, dir1); strcpy (tmp2, dir2); strcat (tmp1, "/"); strcpy (tmp, tmp1); strcat (tmp, tmp2); #if DEBUG printf ("dircat (%s)\n", tmp); #endif return tmp; } static int skip_blanks (char * name, int i) { while ((name [i] == ' ') && (name [i] != '\0')) { i++; } return i; } static int getnext (char * part, char * components, int i) { int j = 0; i = skip_blanks (components, i); if (components [i] == '\0') { return -1; } while ((components [i] != ' ') && (components [i] != '\0')) { part [j++] = components [i++]; part [j] = '\0'; } return i; } static void print_usage (void) { printf ("usage: m3where [options] [units]\n"); printf ("-b build with this template and in this directory (default=\'%s\')\n", build_dir); printf ("-T use templates in specified directory (default=\'%s\')\n", template_dir); printf ("-d start in this directory (default=\'%s\')\n", start_dir); printf ("-v verbose\n"); printf ("-h show hidden\n"); printf ("- pass this argument to quake\n"); printf (" ... call quake with each unit\n"); printf ("\n"); } /* * parse the command line */ static void parse_command_line (int argc, char ** argv) { int i = 1; while (i < argc) { if (strcmp (argv [i], "-b") == 0) { /* -b) shift ; build_dir="$1" ; template="$1" ;; */ if (i++ >= argc) break; strcpy (build_dir, argv [i]); strcpy (template, argv [i]); } else if (strcmp (argv [i], "-T") == 0) { /* -T) shift ; template_dir="$1" ;; */ if (i++ >= argc) break; strcpy (template_dir, argv [i]); } else if (strcmp (argv [i], "-d") == 0) { /* -d) shift ; start_dir="$1" ;; */ if (i++ >= argc) break; strcpy (start_dir, argv [i]); } else if (strcmp (argv [i], "-v") == 0) { /* -v) verbose="y" ;; */ strcpy (verbose, "y"); } else if (strcmp (argv [i], "-h") == 0) { /* -h) show_hidden="show_hidden" ;; */ strcpy (show_hidden, "show_hidden"); } else if (argv [i] [0] == '-') { /* quake args */ /* -*) quake_args="$quake_args $1" ;; */ strcat (quake_args, " "); strcat (quake_args, argv [i]); } else { /* units */ /* *) units="$units $1" ;; */ strcat (units, " "); strcat (units, argv [i]); } i++; } #if DEBUG printf (" --------------------------- \n"); for (i = 0; i < argc; i++) { printf ("argv [%d] = %s\n", i, argv [i]); } printf (" --------------------------- \n"); #endif } /* * get basename */ static char * basename (char * name) { int i, len; i = len = strlen (name); while ((--i >= 0) && (name [i] != '/') && (name [i] != '\\')) ; /* i could be (-1) */ strncpy (basetmp, &name [i+1], len - i + 1); #if DEBUG printf ("basename (%s) = %s\n", name, basetmp); #endif return basetmp; } /* * get to the initial directory */ static void goto_initial_directory (void) { chdir (start_dir); /* cd "$start_dir" */ getcwd (start_dir, PATH_LEN); /* start_dir=`pwd` */ strcpy (base, basename (start_dir));/* base=`basename "$start_dir"` */ chdir (".."); getcwd (parent, PATH_LEN); /* parent=`cd .. ; pwd` */ chdir (start_dir); #if DEBUG printf ("start_dir = %s, parent = %s, base = %s\n", start_dir, parent, base); #endif } /* * move to the directory with derived objects */ static void goto_dir_with_derived_objects (void) { if (strcmp (base, build_dir) == 0) { /* if [ $base = $build_dir ] */ strcpy (package_dir, parent); /* package_dir=$parent */ } else if (is_dir (build_dir)) { /* elif [ -d "$build_dir" ] */ strcpy (package_dir, start_dir); /* package_dir="$start_dir" */ printf ("--- cd %s ---\n", build_dir); chdir (build_dir); /* cd "$build_dir" */ } else if (is_dir (dircat ("..", build_dir))) { /* elif [ -d "../$build_dir" ] */ /* we're in a sibling directory (probably "src") */ strcpy (package_dir, parent); /* set package_dir=$parent */ chdir (dircat ("..", build_dir)); /* cd "../$build_dir" */ } else { /* echo "m3where: cannot locate build directory $build_dir" */ printf ("m3where: cannot locate build directory %s\n", build_dir); exit (-1); } /* package=`basename "$package_dir"` */ strcpy (package, basename (package_dir)); #if DEBUG printf ("package_dir = %s, build_dir = %s, package = %s\n", package_dir, build_dir, package); #endif } /* * find a .M3EXPORTS file */ static void check_for_exportsfile (void) { if (! readable (".M3EXPORTS")) { /* if [ ! -r ".M3EXPORTS" ] */ getcwd (tmp, PATH_LEN); /* echo "m3where: missing .M3EXPORTS file in `pwd`" */ printf ("m3where: missing .M3EXPORTS file in %s\n", tmp); exit (-1); } } /* * build the query */ static void build_query (int argc, char ** argv) { FILE * fd; int i; /* query="/tmp/m3find.$$" - see query init */ if ((fd = fopen (query, "w")) == NULL) { printf ("m3where: cannot create %s\n", query); exit (-1); } /* echo "% m3where $*" >$query */ fprintf (fd, "%% "); for (i = 0; i < argc; i++) { fprintf (fd, "%s ", argv [i]); } fprintf (fd, "\n"); if (strlen (units) == 0) { /* if [ "x$units" = "x" ] */ /* echo "enum_units(\"$show_hidden\")" >>$query */ fprintf (fd, "enum_units (\"%s\")\n", show_hidden); } else { i = 0; while ((i = getnext (unit, units, i)) > 0) { /* for u in $units */ /* echo "find_unit($u, \"$show_hidden\")" >>$query */ fprintf (fd, "find_unit (%s, \"%s\")\n", unit, show_hidden); } } fclose (fd); } extern char ** environ; static int execute (char * quake, char * package_dir, char * package, char * build_dir, char * template_dir, char * quake_args, char * exports, char * query) { /* quake -DPACKAGE_DIR=$package_dir -DPACKAGE=$package * -DBUILD_DIR=$build_dir $template_dir/$template $quake_args * .M3EXPORTS query */ char args [30] [PATH_LEN]; int i = 0, j = 0, status; char quake_arg [PATH_LEN]; char * argv [30]; strcpy (args [0], quake); argv [0] = &args [0][0]; strcpy (args [1], "-DPACKAGE_DIR="); strcat (args [1], package_dir); argv [1] = &args [1][0]; strcpy (args [2], "-DPACKAGE="); strcat (args [2], package); argv [2] = &args [2][0]; strcpy (args [3], "-DBUILD_DIR="); strcat (args [3], build_dir); argv [3] = &args [3][0]; strcpy (args [4], template_dir); argv [4] = &args [4][0]; while ((i = getnext (quake_arg, quake_args, i)) > 0) { strcpy (args [5 + j], quake_arg); argv [5 + j] = &args [5 + j][0]; j++; } strcpy (args [5 + j], exports); argv [5 + j] = &args [5 + j][0]; j++; strcpy (args [5 + j], query); argv [5 + j] = &args [5 + j][0]; argv [5 + j + 1] = 0; #if DEBUG j = 0; printf ("-----------------------------\n"); while (argv [j]) { printf ("argv [%d] = %s\n", j, argv [j]); j++; } printf ("-----------------------------\n"); #endif if (vfork () == 0) { /* child */ if (execve (quake, argv, environ) < 0) { printf ("m3where: cannot execute %s\n", quake); exit (-1); } } /* parent */ wait (&status); return status; } /* * prepare for the worst... * * trap 'rm -f $query ; exit 1' 1 2 3 15 */ /* * evaulate the query */ static void evaluate_query (void) { if (strcmp (verbose, "y") == 0) { /* if [ x"$verbose" = xy ] */ /* echo "$quake -DPACKAGE_DIR=$package_dir -DPACKAGE=$package * -DBUILD_DIR=$build_dir $template_dir/$template $quake_args * .M3EXPORTS $query" */ printf ("%s -DPACKAGE_DIR=%s -DPACKAGE=%s ", quake, package_dir, package); printf ("-DBUILD_DIR=%s %s/%s %s .M3EXPORTS %s\n", build_dir, template_dir, template, quake_args, query); } /* $quake -DPACKAGE_DIR=$package_dir -DPACKAGE=$package * -DBUILD_DIR=$build_dir $template_dir/$template $quake_args * .M3EXPORTS $query */ if (execute (quake, package_dir, package, build_dir, dircat (template_dir, template), quake_args, ".M3EXPORTS", query) < 0) { unlink (query); /* rm -f $query */ exit (-1); } unlink (query); /* rm -f $query */ } int main (int argc, char ** argv, char ** envp) { parse_command_line (argc, argv); goto_initial_directory (); goto_dir_with_derived_objects (); check_for_exportsfile (); build_query (argc, argv); evaluate_query (); return 0; }