Subject: Re: Static Link - ls on solaris

From: Keith Patton <[email-masked]>
Date: Tue, 10 Mar 1998 07:38:09 -0600

Graham Potts wrote:

> Hi,
> I noticed a post from yourself in the wu-ftpd mailing list regarding a
> statically linked ls
> for Solaris. I don't suppose you could tell me how you did that? I've
> been trying to link ls from the gnu file utils kit with no great success
> so far. Any help would be much appreciated.
>
> Thanks,
> Graham Potts

For the record:

   How to ceate a static image of ls..

.
First get the fileutilies from gnu:

    ( from the faq's )

    9.Programs (ls, gzip, tar) work for real users, not for anonymous
users, giving errors like 425
      Can't create data socket (0.0.0.0,20): Bad file number or simply no
output.

      First, consider if you can't relink them staticly so the shared
libraries aren't needed. You
      can get the GNU fileutils from :
<URL:ftp://prep.ai.mit.edu/pub/gnu/fileutils-3.16.tar.gz>
      (version numbers may vary).

Then apply this patch:

    I did not have any luck since the version are different, but one can
read it and make the
changes manually in just a few minutes...

*** fileutils-3.13/src/Makefile Fri Dec 13 17:24:37 1996
--- old/fileutils-3.13/src/Makefile     Fri Dec 13 16:18:22 1996
***************
*** 68,74 ****
  cp_SOURCES = cp.c cp-aux.c cp-hash.c
  dir_SOURCES = ls.c ls-dir.c
  vdir_SOURCES = ls.c ls-vdir.c
! ls_SOURCES = ls.c ls-ls.c
  
  BUILT_SOURCES = #M#dircolors.h
  PERL = /home/sdu/cel95eig/bin/mine/perl
--- 68,75 ----
  cp_SOURCES = cp.c cp-aux.c cp-hash.c
  dir_SOURCES = ls.c ls-dir.c
  vdir_SOURCES = ls.c ls-vdir.c
! static-ls_SOURCES = static-ls.c
! ls_SOURCES = ls.c ls-ls.c $(static-ls_SOURCES)
  
  BUILT_SOURCES = #M#dircolors.h
  PERL = /home/sdu/cel95eig/bin/mine/perl
***************
*** 87,94 ****
  LEX = @LEX@
  YACC = byacc
  CPPFLAGS = 
! CFLAGS = -g -O
! LDFLAGS = 
  LIBS = -lintl -lgen 
  
  COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
--- 88,95 ----
  LEX = @LEX@
  YACC = byacc
  CPPFLAGS = 
! CFLAGS = -static -g -O
! LDFLAGS = -static
  LIBS = -lintl -lgen 
  
  COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
***************
*** 136,142 ****
  vdir_OBJECTS = ls$o ls-vdir$o
  EXTRA_vdir_SOURCES =
  vdir_LDADD = $(LDADD)
! ls_OBJECTS = ls$o ls-ls$o
  EXTRA_ls_SOURCES =
  ls_LDADD = $(LDADD)
  mkdir_SOURCES = mkdir.c
--- 137,144 ----
  vdir_OBJECTS = ls$o ls-vdir$o
  EXTRA_vdir_SOURCES =
  vdir_LDADD = $(LDADD)
! static-ls_OBJECTS = static-ls$o
! ls_OBJECTS = ls$o ls-ls$o $(static-ls_OBJECTS)
  EXTRA_ls_SOURCES =
  ls_LDADD = $(LDADD)
  mkdir_SOURCES = mkdir.c
*** fileutils-3.13/src/static-ls.c      Fri Dec 13 16:13:44 1996
--- fileutils-3.13/src/static-ls.c      Fri Dec 11 15:29:46 1996
***************
*** 0 ****
--- 1,230 ----
+ /* static-ls.c rec.1, by Emil Isberg <[email-masked]> */
+ /* static-ls.c rev.2, by Brett Porter <[email-masked]>*/
+ /* static-ls.c rev.2.1, by Emil Isberg <[email-masked]> */
+ /*  for gnufileutils ..  under Solaris 2.5 */
+ /* To compile .. get the lates version of gnufileutil .. */
+ /*  add this file */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <limits.h>
+ #include <sys/types.h>
+ #include <sys/uio.h>
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ 
+ #define FPASSWD "/etc/passwd"
+ #define FGROUP  "/etc/group"
+ 
+ char *dlopen()  { return 0;}
+ int   dlclose() { return 0;}
+ char *dlsym()   { return 0;}
+ char *dlerror() { return "dynamic linking not loaded";}
+ 
+ typedef struct {
+   uid_t uid;
+   char *user_name;
+ } pw_entry;
+ 
+ typedef struct {
+   gid_t gid;
+   char *group_name;
+ } group_entry;
+ 
+ static pw_entry    *pw_array = NULL;
+ static group_entry *group_array = NULL;
+ 
+ static void fill_pw_array (void);
+ static void fill_group_array (void);
+ 
+ static void
+ fill_pw_array (void)
+ {
+   int fd;
+   int ok;
+   static char *pw_buf;
+   struct stat statbuf;
+   char *cp;
+   int n_entries;
+   int n_read;
+   int entry;
+ 
+   fd = open (FPASSWD, O_RDONLY);
+   if (fd < 0) {
+     fprintf (stderr, "Error opening password file.\n");
+     return;
+   }
+ 
+   ok = fstat (fd, &statbuf);
+   if (ok != 0) {
+     fprintf (stderr, "Error stat-ing passwd file.\n");
+     close (fd);
+     return;
+   }
+ 
+   pw_buf = malloc (statbuf.st_size + 1);
+   if (pw_buf == NULL) {
+     fprintf (stderr, "Error allocating memory.\n");
+     close (fd);
+     return;
+   }
+ 
+   n_read = read (fd, pw_buf, (size_t) statbuf.st_size);
+   if (n_read !=  statbuf.st_size) {
+     perror (NULL);
+     fprintf (stderr, "Error reading password file.\n");
+     free (pw_buf);
+     close (fd);
+     return;
+   }
+   pw_buf [statbuf.st_size] = '\0';
+   close (fd);
+ 
+   n_entries = 0;
+   for (cp = pw_buf; *cp != '\0'; cp++) {
+     if (*cp == '\n')
+       n_entries++;
+   }
+ 
+   pw_array = (pw_entry *) malloc ((n_entries + 1) * sizeof (pw_entry));
+   if (pw_array == NULL) {
+     fprintf (stderr, "Error allocating memory.\n");
+     free (pw_buf);
+     return;
+   }
+ 
+   pw_array [n_entries].uid = -1;
+   cp = pw_buf;
+   for (entry = 0; entry < n_entries; entry++) {
+     pw_array [entry].user_name = cp;
+     while (*cp != ':')
+       cp++;
+     *cp++ = '\0';
+     while (*cp != ':')
+       cp++;
+     cp++;
+     pw_array [entry].uid = atoi (cp);
+     while (*cp != '\n')
+       cp++;
+     cp++;
+   }
+ }
+ 
+ 
+ static void
+ fill_group_array (void)
+ {
+   int fd;
+   int ok;
+   static char *group_buf;
+   struct stat statbuf;
+   char *cp;
+   int n_entries;
+   int n_read;
+   int entry;
+ 
+   fd = open (FGROUP, O_RDONLY);
+   if (fd < 0) {
+     fprintf (stderr, "Error opening group file.\n");
+     return;
+   }
+ 
+   ok = fstat (fd, &statbuf);
+   if (ok != 0) {
+     fprintf (stderr, "Error stat-ing group file.\n");
+     close (fd);
+     return;
+   }
+ 
+   group_buf = malloc (statbuf.st_size + 1);
+   if (group_buf == NULL) {
+     fprintf (stderr, "Error allocating memory.\n");
+     close (fd);
+     return;
+   }
+ 
+   n_read = read (fd, group_buf, (size_t) statbuf.st_size);
+   if (n_read !=  statbuf.st_size) {
+     perror (NULL);
+     fprintf (stderr, "Error reading group file.\n");
+     free (group_buf);
+     close (fd);
+     return;
+   }
+   group_buf [statbuf.st_size] = '\0';
+   close (fd);
+ 
+   n_entries = 0;
+   for (cp = group_buf; *cp != '\0'; cp++) {
+     if (*cp == '\n')
+       n_entries++;
+   }
+ 
+   group_array =
+     (group_entry *) malloc ((n_entries + 1) * sizeof (group_entry));
+   if (group_array == NULL) {
+     fprintf (stderr, "Error allocating memory.\n");
+     free (group_buf);
+     return;
+   }
+ 
+   group_array [n_entries].gid = -1;
+   cp = group_buf;
+   for (entry = 0; entry < n_entries; entry++) {
+     group_array [entry].group_name = cp;
+     while (*cp != ':')
+       cp++;
+     *cp++ = '\0';
+     while (*cp != ':')
+       cp++;
+     cp++;
+     group_array [entry].gid = atoi (cp);
+     while (*cp != '\n')
+       cp++;
+     cp++;
+   }
+ }
+ 
+ char *
+ getuser(uid_t uid)
+ {
+   pw_entry *p_pw;
+   static char uid_str [11];
+ 
+   if (pw_array == NULL)
+     fill_pw_array ();
+   if (pw_array == NULL) {
+     sprintf (uid_str, "%lu", uid);
+     return uid_str;
+   }
+ 
+   for (p_pw = pw_array; p_pw->uid != -1; p_pw++) {
+     if (p_pw->uid == uid)
+       return p_pw->user_name;
+   }
+   sprintf (uid_str, "%lu", uid);
+   return uid_str;
+ }
+  
+ char *
+ getgroup(gid_t gid)
+ {
+   group_entry *p_group;
+   static char gid_str [11];
+ 
+   if (group_array == NULL)
+     fill_group_array ();
+   if (group_array == NULL) {
+     sprintf (gid_str, "%lu", gid);
+     return gid_str;
+   }
+ 
+   for (p_group = group_array; p_group->gid != -1; p_group++) {
+     if (p_group->gid == gid)
+       return p_group->group_name;
+   }
+   sprintf (gid_str, "%lu", gid);
+   return gid_str;
+ }