#if 0 /* -*- mode: c; c-file-style: "stroustrup"; tab-width: 8; -*- set -e; TRG=`basename $0 .c`; rm -f "$TRG" WARN="-Wall -Wstrict-prototypes -pedantic -Wno-long-long" WARN="$WARN -Wcast-align -Wpointer-arith " # -Wfloat-equal #-Werror WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion date=`date`; set -x #${CC:-gcc} -ggdb $WARN "$@" -o "$TRG" "$0" -DCDATE="\"$date\"" ${CC:-gcc} -O2 $WARN "$@" -o "$TRG" "$0" -DCDATE="\"$date\"" exit 0 */ #endif /* * $Id; stfufs-server-launcher.c $ * * Author: Tomi Ollila <> * * Copyright (c) 2008 Tomi Ollila * All rights reserved * * Created: Tue Jan 22 16:45:56 EET 2008 too * Last modified: Thu Jan 31 20:02:46 EET 2008 too */ /* * findpath.c * * Created; Sun Apr 12 20:22:30 1998 too * Last Modified; Tue Apr 14 12:34:28 1998 too */ #include #include #include #include /* * This function is checked to be robust with all path 3 types possible * (cmd has relative, absolute or no path component) * The returned path will always contain at least one '/'. (if not NULL). * Overflow testing for internal buffer is always done. */ static char * findpath(const char * cmd) { static char buf[1024]; char * pd = NULL; buf[0] = '\0'; /* this will (and needs to) stay '\0' */ if (strchr(cmd, '/')) /* absolute or relative path given */ { int l, state; const char * ps; if (cmd[0] != '/') { #if 1 if (getcwd(buf + 1, sizeof buf - 128) == NULL) return NULL; #else strcpy(buf + 1, "/this/is/a/test/entry/"); /* with tailing '/' */ #endif l = strlen(buf + 1); } else l = 0; if (l + strlen(cmd) >= sizeof buf - 64) return NULL; ps = cmd; pd = buf + l; /* buf + 1 + l - 1 */ if (*pd++ != '/') *pd++ = '/'; state = 1; /* delete extra `/./', '/../' and '//':s from the path */ while (*ps) { switch (state) { case 0: if (*ps == '/') state = 1; else state = 0; break; case 1: if (*ps == '.') { state = 2; break; } if (*ps == '/') pd--; else state = 0; break; case 2: if (*ps == '/') { state = 1; pd -= 2; break; } if (*ps == '.') state = 3; else state = 0; break; case 3: if (*ps != '/') { state = 0; break; } state = 1; pd -= 4; while (*pd != '/' && *pd != '\0') pd--; if (*pd == '\0') pd++; state = 1; break; } *pd++ = *ps++; } } else /* no slashes ('/') in cmd */ { char * path = getenv("PATH"); char * s; unsigned int cl = strlen(cmd) + 1; for (s = path; s; path = s + 1) { char * p; unsigned int l; s = strchr(path, ':'); l = s? (unsigned int)(s - path): strlen(path); if (l + cl > sizeof buf - 64) continue; memcpy(buf + 1, path, l); p = buf + l; /* buf + 1 + l - 1 */ if (*p++ != '/') *p++ = '/'; memcpy(p, cmd, cl); if (access(buf + 1, X_OK) == 0) { pd = p /* + cl*/ ; break; } } } if (pd) { do pd--; while (*pd != '/'); /* there is at least one '/' */ if (*(pd - 1) == '\0') pd++; *pd = '\0'; return buf + 1; } return NULL; } #include "version.h" extern char ** environ; int main(int argc, char ** argv) { char * path = findpath(argv[0]); char * p; char av0[16] = "stfufs-server"; char * av[2] = { NULL, NULL }; const char * arg; /* puts(av0); exit(0); */ do { if (path) { p = strrchr(path, '/'); if (p++ != NULL) break; } fprintf(stderr, "Server execution path unknown\n"); return 1; } while (0); arg = (argc >= 2)? ((strlen(argv[1]) < 10)? argv[1]: PROTVER): "2"; if (strcmp(arg, PROTVER) != 0) fprintf(stderr, "Note: default client and server protocol versions" " differ (%s <> %s)\n" "Consider updating both to the same" " (newer) version\n", arg, PROTVER); sprintf(p, "lib/stfufs/stfufs-server-%s", arg); av[0] = av0; execve(path, av, environ); fprintf(stderr, "Requested server does not exist (%s)\n", arg); return 1; }