Back to index

plt-scheme  4.2.1
Classes | Defines | Functions | Variables
ustart.c File Reference
#include <sys/types.h>
#include <sys/uio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

Go to the source code of this file.

Classes

struct  X_flag_entry

Defines

#define LD_LIB_PATH   "LD_LIBRARY_PATH"

Functions

static int is_x_flag (char *s)
static void write_str (int fd, char *s)
static char * string_append (char *s1, char *s2)
static char * copy_string (char *s1)
static char * do_path_append (char *s1, int l1, char *s2)
static char * path_append (char *s1, char *s2)
static int executable_exists (char *path)
static int as_int (char *_c)
static int has_slash (char *s)
char * absolutize (char *p, char *d)
static char * next_string (char *s)
int main (int argc, char **argv)

Variables

char * config = "cOnFiG:[***************************"
char * binary_type_hack = "bINARy tYPe:ezic"
char * _coldir = "****************************************************************"
static int _coldir_offset = 19
static X_flag_entry X_flags []

Class Documentation

struct X_flag_entry

Definition at line 57 of file ustart.c.

Class Members
int arg_count
char * flag

Define Documentation

#define LD_LIB_PATH   "LD_LIBRARY_PATH"

Function Documentation

char* absolutize ( char *  p,
char *  d 
)

Definition at line 201 of file ustart.c.

{
  int l1;

  if (!p[0])
    return p;

  if (p[0] == '/')
    return p;
  
  /* Strip filename off d: */
  l1 = strlen(d);
  while (l1 && (d[l1- 1] != '/')) {
    l1--;
  }
  if (l1)
    return do_path_append(d, l1, p);
  else
    return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int as_int ( char *  _c) [static]

Definition at line 185 of file ustart.c.

{
  unsigned char *c = (unsigned char *)_c;
  return c[0] | ((int)c[1] << 8) | ((int)c[2] << 16)  | ((int)c[3] << 24);
}

Here is the caller graph for this function:

static char* copy_string ( char *  s1) [static]

Definition at line 139 of file ustart.c.

{
  int l1;
  char *s;

  if (!s1) return NULL;

  l1 = strlen(s1);

  s  = (char *)malloc(l1 + 1);

  memcpy(s, s1, l1 + 1);

  return s;
}

Here is the caller graph for this function:

static char* do_path_append ( char *  s1,
int  l1,
char *  s2 
) [static]

Definition at line 155 of file ustart.c.

{
  int l2;
  char *s;

  l2 = strlen(s2);

  s  = (char *)malloc(l1 + l2 + 2);

  memcpy(s, s1, l1);
  if (s[l1 - 1] != '/') {
    s[l1++] = '/';
  }

  memcpy(s + l1, s2, l2);
  s[l1 + l2] = 0;

  return s;
}

Here is the caller graph for this function:

static int executable_exists ( char *  path) [static]

Definition at line 180 of file ustart.c.

{
  return (access(path, X_OK) == 0);
}

Here is the caller graph for this function:

static int has_slash ( char *  s) [static]

Definition at line 191 of file ustart.c.

{
  while (*s) {
    if (s[0] == '/')
      return 1;
    s++;
  }
  return 0;
}

Here is the caller graph for this function:

static int is_x_flag ( char *  s) [static]

Definition at line 85 of file ustart.c.

{
  X_flag_entry *x = X_flags;

  while (x->flag) {
    if (!strcmp(x->flag, s))
      return x->arg_count + 1;
    x++;
  }

  return 0;
}

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 227 of file ustart.c.

{
  char *me = argv[0], *data, **new_argv;
  char *exe_path, *lib_path, *dll_path;
  int start, prog_end, end, count, fd, v, x11;
  int argpos, inpos, collcount = 1;

  if (config[7] == '[') {
    write_str(2, argv[0]);
    write_str(2, ": this is an unconfigured starter\n");
    return 1;
  }

  if (me[0] == '/') {
    /* Absolute path */
  } else if (has_slash(me)) {
    /* Relative path with a directory: */
    char *buf;
    long buflen = 4096;
    buf = (char *)malloc(buflen);
    me = path_append(getcwd(buf, buflen), me);
  } else {
    /* We have to find the executable by searching PATH: */
    char *path = copy_string(getenv("PATH")), *p, *m;
    int more;

    if (!path) {
      path = "";
    }

    while (1) {
      /* Try each element of path: */
      for (p = path; *p && (*p != ':'); p++) { }
      if (*p) {
       *p = 0;
       more = 1;
      } else
       more = 0;

      if (!*path)
       break;

      m = path_append(path, me);

      if (executable_exists(m)) {
       if (m[0] != '/')
         m = path_append(getcwd(NULL, 0), m);
       me = m;
       break;
      }
      free(m);

      if (more)
       path = p + 1;
      else
       break;
    }
  }
  
  /* me is now an absolute path to the binary */

  /* resolve soft links */
  while (1) {
    int len, bufsize = 127;
    char *buf;
    buf = (char *)malloc(bufsize + 1);
    len = readlink(me, buf, bufsize);
    if (len < 0) {
      if (errno == ENAMETOOLONG) {
       /* Increase buffer size and try again: */
       bufsize *= 2;
       buf = (char *)malloc(bufsize + 1);
      } else
       break;
    } else {
      /* Resolve buf relative to me: */
      buf[len] = 0;
      buf = absolutize(buf, me);
      me = buf;
      buf = (char *)malloc(bufsize + 1);
    }
  }

  start = as_int(config + 8);
  prog_end = as_int(config + 12);
  end = as_int(config + 16);
  count = as_int(config + 20);
  x11 = as_int(config + 24);

  {
    int offset, len;
    offset = _coldir_offset;
    while (1) {
      len = strlen(_coldir + offset);
      offset += len + 1;
      if (!_coldir[offset])
       break;
      collcount++;
    }
  }

  data = (char *)malloc(end - prog_end);
  new_argv = (char **)malloc((count + argc + (2 * collcount) + 8) * sizeof(char*));

  fd = open(me, O_RDONLY, 0);
  lseek(fd, prog_end, SEEK_SET);
  read(fd, data, end - prog_end);
  close(fd);
  
  exe_path = data;
  data = next_string(data);

  lib_path = data;
  data = next_string(data);

  exe_path = absolutize(exe_path, me);
  lib_path = absolutize(lib_path, me);

# ifdef OS_X
#  define LD_LIB_PATH "DYLD_LIBRARY_PATH"
# else
#  define LD_LIB_PATH "LD_LIBRARY_PATH"
# endif

  if (*lib_path) {
    dll_path = getenv(LD_LIB_PATH);
    if (!dll_path) {
      dll_path = "";
    }
    dll_path = string_append(dll_path, ":");
    dll_path = string_append(lib_path, dll_path);
    dll_path = string_append(LD_LIB_PATH "=", dll_path);
    putenv(dll_path);
  }

  new_argv[0] = me;

  argpos = 1;
  inpos = 1;

  /* Keep all X11 flags to the front: */
  if (x11) {
    int n;
    while (inpos < argc) {
      n = is_x_flag(argv[inpos]);
      if (!n)
       break;
      if (inpos + n > argc) {
       write_str(2, argv[0]);
       write_str(2, ": missing an argument for ");
       write_str(2, argv[inpos]);
       write_str(2, "\n");
       return 1;
      }
      while (n--) {
       new_argv[argpos++] = argv[inpos++];
      }
    }
  }

  /* Add -X and -S flags */
  {
    int offset, len;
    offset = _coldir_offset;
    new_argv[argpos++] = "-X";
    new_argv[argpos++] = _coldir + offset;
    while (1) {
      len = strlen(_coldir + offset);
      offset += len + 1;
      if (!_coldir[offset])
       break;
      new_argv[argpos++] = "-S";
      new_argv[argpos++] = _coldir + offset;
    }
  }

  /* Add built-in flags: */
  while (count--) {
    new_argv[argpos++] = data;
    data = next_string(data);
  }

  /* Propagate new flags (after the X11 flags) */
  while (inpos < argc) {
    new_argv[argpos++] = argv[inpos++];
  }

  new_argv[argpos] = NULL;

  /* Execute the original binary: */

  v = execv(exe_path, new_argv);

  write_str(2, argv[0]);
  write_str(2, ": failed to start ");
  write_str(2, exe_path);
  write_str(2, "\n");

  return v;
}

Here is the call graph for this function:

static char* next_string ( char *  s) [static]

Definition at line 222 of file ustart.c.

{
  return s + strlen(s) + 1;
}

Here is the caller graph for this function:

static char* path_append ( char *  s1,
char *  s2 
) [static]

Definition at line 175 of file ustart.c.

{
  return do_path_append(s1, strlen(s1), s2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* string_append ( char *  s1,
char *  s2 
) [static]

Definition at line 122 of file ustart.c.

{
  int l1, l2;
  char *s;

  l1 = strlen(s1);
  l2 = strlen(s2);

  s  = (char *)malloc(l1 + l2 + 1);

  memcpy(s, s1, l1);
  memcpy(s + l1, s2, l2);
  s[l1 + l2] = 0;

  return s;
}

Here is the caller graph for this function:

static void write_str ( int  fd,
char *  s 
) [static]

Definition at line 98 of file ustart.c.

{
  write(fd, s, strlen(s));
}

Here is the caller graph for this function:


Variable Documentation

char* _coldir = "****************************************************************"

Definition at line 35 of file ustart.c.

int _coldir_offset = 19 [static]

Definition at line 55 of file ustart.c.

char* binary_type_hack = "bINARy tYPe:ezic"

Definition at line 29 of file ustart.c.

char* config = "cOnFiG:[***************************"

Definition at line 27 of file ustart.c.

X_flag_entry X_flags[] [static]
Initial value:
 {
  { "-display", 1 },
  { "-geometry", 1 },
  { "-bg", 1 },
  { "-background", 1 },
  { "-fg", 1 },
  { "-foreground", 1 },
  { "-fn", 1 },
  { "-font", 1 },
  { "-iconic", 0 },
  { "-name", 1 },
  { "-rv", 0 },
  { "-reverse", 0 },
  { "+rv", 0 },
  { "-selectionTimeout", 1 },
  { "-synchronous", 0 },
  { "-title", 1 },
  { "-xnllanguage", 1 },
  { "-xrm", 1 },
  { "-singleInstance", 0 },
  { NULL, 0 }
}

Definition at line 62 of file ustart.c.