Accomodate older glibc, which also lacks the module syscalls
[oweals/busybox.git] / ls.c
diff --git a/ls.c b/ls.c
index a5574a52e87931954cc0b9d0c62cde04fee4ac86..8d0282dfec656da0d5b1d6ef8808fcf43d7e229d 100644 (file)
--- a/ls.c
+++ b/ls.c
@@ -21,7 +21,7 @@
 /*
  * To achieve a small memory footprint, this version of 'ls' doesn't do any
  * file sorting, and only has the most essential command line switches
- * (i.e. the ones I couldn't live without :-) All features which involve
+ * (i.e., the ones I couldn't live without :-) All features which involve
  * linking in substantial chunks of libc can be disabled.
  *
  * Although I don't really want to add new features to this program to
@@ -50,7 +50,6 @@ enum {
 
 /************************************************************************/
 
-#include "busybox.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -58,15 +57,17 @@ enum {
 #include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
-#ifdef BB_FEATURE_LS_TIMESTAMPS
-#include <time.h>
-#endif
 #include <string.h>
 #include <stdlib.h>
-
 #include <fcntl.h>
 #include <signal.h>
+#include <termios.h>
 #include <sys/ioctl.h>
+#include "busybox.h"
+
+#ifdef BB_FEATURE_LS_TIMESTAMPS
+#include <time.h>
+#endif
 
 #ifndef MAJOR
 #define MAJOR(dev) (((dev)>>8)&0xff)
@@ -156,9 +157,9 @@ struct dnode {                              /* the basic node */
 };
 typedef struct dnode dnode_t;
 
-struct dnode **list_dir(char *);
-struct dnode **dnalloc(int);
-int list_single(struct dnode *);
+static struct dnode **list_dir(char *);
+static struct dnode **dnalloc(int);
+static int list_single(struct dnode *);
 
 static unsigned int disp_opts;
 static unsigned int style_fmt;
@@ -186,7 +187,7 @@ static unsigned short column_width = COLUMN_WIDTH;
 static int status = EXIT_SUCCESS;
 
 #ifdef BB_FEATURE_HUMAN_READABLE
-unsigned long ls_disp_hr = KILOBYTE;
+static unsigned long ls_disp_hr = 0;
 #endif
 
 static int my_stat(struct dnode *cur)
@@ -256,7 +257,7 @@ static int is_subdir(struct dnode *dn)
                        strcmp(dn->name, "..") != 0);
 }
 
-int countdirs(struct dnode **dn, int nfiles)
+static int countdirs(struct dnode **dn, int nfiles)
 {
        int i, dirs;
 
@@ -268,7 +269,7 @@ int countdirs(struct dnode **dn, int nfiles)
        return(dirs);
 }
 
-int countsubdirs(struct dnode **dn, int nfiles)
+static int countsubdirs(struct dnode **dn, int nfiles)
 {
        int i, subdirs;
 
@@ -280,7 +281,7 @@ int countsubdirs(struct dnode **dn, int nfiles)
        return subdirs;
 }
 
-int countfiles(struct dnode **dnp)
+static int countfiles(struct dnode **dnp)
 {
        int nfiles;
        struct dnode *cur;
@@ -293,7 +294,7 @@ int countfiles(struct dnode **dnp)
 }
 
 /* get memory to hold an array of pointers */
-struct dnode **dnalloc(int num)
+static struct dnode **dnalloc(int num)
 {
        struct dnode **p;
 
@@ -303,7 +304,8 @@ struct dnode **dnalloc(int num)
        return(p);
 }
 
-void dfree(struct dnode **dnp)
+#ifdef BB_FEATURE_LS_RECURSIVE
+static void dfree(struct dnode **dnp)
 {
        struct dnode *cur, *next;
 
@@ -318,8 +320,9 @@ void dfree(struct dnode **dnp)
        }
        free(dnp);      /* free the array holding the dnode pointers */
 }
+#endif
 
-struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which)
+static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which)
 {
        int dncnt, i, d;
        struct dnode **dnp;
@@ -359,7 +362,7 @@ struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which)
 
 /*----------------------------------------------------------------------*/
 #ifdef BB_FEATURE_LS_SORTFILES
-int sortcmp(struct dnode *d1, struct dnode *d2)
+static int sortcmp(struct dnode *d1, struct dnode *d2)
 {
        int cmp, dif;
 
@@ -396,7 +399,7 @@ int sortcmp(struct dnode *d1, struct dnode *d2)
 }
 
 /*----------------------------------------------------------------------*/
-void shellsort(struct dnode **dn, int size)
+static void shellsort(struct dnode **dn, int size)
 {
        struct dnode *temp;
        int gap, i, j;
@@ -420,7 +423,7 @@ void shellsort(struct dnode **dn, int size)
 #endif
 
 /*----------------------------------------------------------------------*/
-void showfiles(struct dnode **dn, int nfiles)
+static void showfiles(struct dnode **dn, int nfiles)
 {
        int i, ncols, nrows, row, nc;
 #ifdef BB_FEATURE_AUTOWIDTH
@@ -481,7 +484,7 @@ void showfiles(struct dnode **dn, int nfiles)
 }
 
 /*----------------------------------------------------------------------*/
-void showdirs(struct dnode **dn, int ndirs)
+static void showdirs(struct dnode **dn, int ndirs)
 {
        int i, nfiles;
        struct dnode **subdnp;
@@ -524,7 +527,7 @@ void showdirs(struct dnode **dn, int ndirs)
 }
 
 /*----------------------------------------------------------------------*/
-struct dnode **list_dir(char *path)
+static struct dnode **list_dir(char *path)
 {
        struct dnode *dn, *cur, **dnp;
        struct dirent *entry;
@@ -543,16 +546,16 @@ struct dnode **list_dir(char *path)
        }
        while ((entry = readdir(dir)) != NULL) {
                /* are we going to list the file- it may be . or .. or a hidden file */
-               if ((strcmp(entry->d_name, ".")==0) && !(disp_opts & DISP_DOT)) continue;
-               if ((strcmp(entry->d_name, "..")==0) && !(disp_opts & DISP_DOT)) continue;
-               if ((entry->d_name[0] ==  '.') && !(disp_opts & DISP_HIDDEN)) continue;
+               if ((strcmp(entry->d_name, ".")==0) && !(disp_opts & DISP_DOT))
+                       continue;
+               if ((strcmp(entry->d_name, "..")==0) && !(disp_opts & DISP_DOT))
+                       continue;
+               if ((entry->d_name[0] ==  '.') && !(disp_opts & DISP_HIDDEN))
+                       continue;
                cur= (struct dnode *)xmalloc(sizeof(struct dnode));
-               cur->fullname = xmalloc(strlen(path)+1+strlen(entry->d_name)+1);
-               strcpy(cur->fullname, path);
-               if (cur->fullname[strlen(cur->fullname)-1] != '/')
-                       strcat(cur->fullname, "/");
-               cur->name= cur->fullname + strlen(cur->fullname);
-               strcat(cur->fullname, entry->d_name);
+               cur->fullname = concat_path_file(path, entry->d_name);
+               cur->name = cur->fullname +
+                               (strlen(cur->fullname) - strlen(entry->d_name));
                if (my_stat(cur))
                        continue;
                cur->next= dn;
@@ -575,9 +578,9 @@ struct dnode **list_dir(char *path)
 }
 
 /*----------------------------------------------------------------------*/
-int list_single(struct dnode *dn)
+static int list_single(struct dnode *dn)
 {
-       int i, len;
+       int i;
        char scratch[BUFSIZ + 1];
 #ifdef BB_FEATURE_LS_TIMESTAMPS
        char *filetime;
@@ -605,12 +608,13 @@ int list_single(struct dnode *dn)
        for (i=0; i<=31; i++) {
                switch (list_fmt & (1<<i)) {
                        case LIST_INO:
-                               printf("%7ld ", dn->dstat.st_ino);
+                               printf("%7ld ", (long int)dn->dstat.st_ino);
                                column += 8;
                                break;
                        case LIST_BLOCKS:
 #ifdef BB_FEATURE_HUMAN_READABLE
-                               fprintf(stdout, "%5s ", format(dn->dstat.st_size, ls_disp_hr));
+                               fprintf(stdout, "%6s ", make_human_readable_str(dn->dstat.st_blocks>>1, 
+                                                       KILOBYTE, (ls_disp_hr==TRUE)? 0: KILOBYTE));
 #else
 #if _FILE_OFFSET_BITS == 64
                                printf("%4lld ", dn->dstat.st_blocks>>1);
@@ -621,11 +625,11 @@ int list_single(struct dnode *dn)
                                column += 5;
                                break;
                        case LIST_MODEBITS:
-                               printf("%10s", (char *)mode_string(dn->dstat.st_mode));
+                               printf("%-10s ", (char *)mode_string(dn->dstat.st_mode));
                                column += 10;
                                break;
                        case LIST_NLINKS:
-                               printf("%4d ", dn->dstat.st_nlink);
+                               printf("%4ld ", (long)dn->dstat.st_nlink);
                                column += 10;
                                break;
                        case LIST_ID_NAME:
@@ -647,14 +651,17 @@ int list_single(struct dnode *dn)
                                        printf("%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev));
                                } else {
 #ifdef BB_FEATURE_HUMAN_READABLE
-                                       fprintf(stdout, "%9s ", format(dn->dstat.st_size, ls_disp_hr));
-#else
+                                       if (ls_disp_hr==TRUE) {
+                                               fprintf(stdout, "%8s ", make_human_readable_str(dn->dstat.st_size, 1, 0));
+                                       } else 
+#endif 
+                                       {
 #if _FILE_OFFSET_BITS == 64
-                                       printf("%9lld ", dn->dstat.st_size);
+                                               printf("%9lld ", (long long)dn->dstat.st_size);
 #else
-                                       printf("%9ld ", dn->dstat.st_size);
-#endif
+                                               printf("%9ld ", dn->dstat.st_size);
 #endif
+                                       }
                                }
                                column += 10;
                                break;
@@ -683,16 +690,16 @@ int list_single(struct dnode *dn)
                                break;
                        case LIST_SYMLINK:
                                if (S_ISLNK(dn->dstat.st_mode)) {
-                                       len= readlink(dn->fullname, scratch, (sizeof scratch)-1);
-                                       if (len > 0) {
-                                               scratch[len]= '\0';
-                                               printf(" -> %s", scratch);
+                                       char *lpath = xreadlink(dn->fullname);
+                                       if (lpath) {
+                                               printf(" -> %s", lpath);
 #ifdef BB_FEATURE_LS_FILETYPES
                                                if (!stat(dn->fullname, &info)) {
                                                        append = append_char(info.st_mode);
                                                }
 #endif
-                                               column += len+4;
+                                               column += strlen(lpath) + 4;
+                                               free(lpath);
                                        }
                                }
                                break;
@@ -735,13 +742,12 @@ extern int ls_main(int argc, char **argv)
        time_fmt= TIME_MOD;
 #endif
 #ifdef BB_FEATURE_AUTOWIDTH
-               ioctl(fileno(stdout), TIOCGWINSZ, &win);
-               if (win.ws_row > 4)
-                       column_width = win.ws_row - 2;
-               if (win.ws_col > 0)
-                       terminal_width = win.ws_col - 1;
+       ioctl(fileno(stdout), TIOCGWINSZ, &win);
+       if (win.ws_row > 4)
+               column_width = win.ws_row - 2;
+       if (win.ws_col > 0)
+               terminal_width = win.ws_col - 1;
 #endif
-       tabstops = 8;
        nfiles=0;
 
        /* process options */
@@ -780,7 +786,7 @@ extern int ls_main(int argc, char **argv)
                                style_fmt = STYLE_LONG;
                                list_fmt |= LIST_LONG;
 #ifdef BB_FEATURE_HUMAN_READABLE
-                               ls_disp_hr = 1;
+                               ls_disp_hr = FALSE;
 #endif
                        break;
                        case 'n': list_fmt |= LIST_ID_NUMERIC; break;
@@ -827,11 +833,9 @@ extern int ls_main(int argc, char **argv)
                        case 'w': terminal_width= atoi(optarg); break;
 #endif
 #ifdef BB_FEATURE_HUMAN_READABLE
-                       case 'h': ls_disp_hr = 0; break;
-                       case 'k': ls_disp_hr = KILOBYTE; break;
-#else
-                       case 'k': break;
+                       case 'h': ls_disp_hr = TRUE; break;
 #endif
+                       case 'k': break;
                        default:
                                goto print_usage_message;
                }
@@ -929,5 +933,5 @@ extern int ls_main(int argc, char **argv)
        return(status);
 
   print_usage_message:
-       usage(ls_usage);
+       show_usage();
 }