summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/ftp/ftpd/ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/ftp/ftpd/ls.c')
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ls.c208
1 files changed, 168 insertions, 40 deletions
diff --git a/crypto/heimdal/appl/ftp/ftpd/ls.c b/crypto/heimdal/appl/ftp/ftpd/ls.c
index 2c85487..9311119 100644
--- a/crypto/heimdal/appl/ftp/ftpd/ls.c
+++ b/crypto/heimdal/appl/ftp/ftpd/ls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -30,9 +30,36 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+#ifndef TEST
#include "ftpd_locl.h"
-RCSID("$Id: ls.c,v 1.14 2000/01/05 13:48:58 joda Exp $");
+RCSID("$Id: ls.c,v 1.20 2001/01/25 01:33:15 joda Exp $");
+
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+
+#define sec_fprintf2 fprintf
+#define sec_fflush fflush
+void
+builtin_ls(FILE *out, const char *file);
+int
+main(int argc, char **argv)
+{
+ int i;
+ for(i = 1; i < argc; i++)
+ builtin_ls(stdout, argv[i]);
+ return 0;
+}
+#endif
struct fileinfo {
struct stat st;
@@ -63,17 +90,23 @@ free_fileinfo(struct fileinfo *f)
free(f->link);
}
-#define LS_DIRS 1
-#define LS_IGNORE_DOT 2
-#define LS_SORT_MODE 12
+#define LS_DIRS (1 << 0)
+#define LS_IGNORE_DOT (1 << 1)
+#define LS_SORT_MODE (3 << 2)
#define SORT_MODE(f) ((f) & LS_SORT_MODE)
-#define LS_SORT_NAME 4
-#define LS_SORT_MTIME 8
-#define LS_SORT_SIZE 12
-#define LS_SORT_REVERSE 16
-
-#define LS_SIZE 32
-#define LS_INODE 64
+#define LS_SORT_NAME (1 << 2)
+#define LS_SORT_MTIME (2 << 2)
+#define LS_SORT_SIZE (3 << 2)
+#define LS_SORT_REVERSE (1 << 4)
+
+#define LS_SIZE (1 << 5)
+#define LS_INODE (1 << 6)
+#define LS_TYPE (1 << 7)
+#define LS_DISP_MODE (3 << 8)
+#define DISP_MODE(f) ((f) & LS_DISP_MODE)
+#define LS_DISP_LONG (1 << 8)
+#define LS_DISP_COLUMN (2 << 8)
+#define LS_DISP_CROSS (3 << 8)
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
@@ -91,6 +124,7 @@ static void
make_fileinfo(const char *filename, struct fileinfo *file, int flags)
{
char buf[128];
+ int file_type = 0;
struct stat *st = &file->st;
file->inode = st->st_ino;
@@ -100,23 +134,36 @@ make_fileinfo(const char *filename, struct fileinfo *file, int flags)
file->bsize = st->st_blocks * 512 / 1024;
#endif
- if(S_ISDIR(st->st_mode))
+ if(S_ISDIR(st->st_mode)) {
file->mode[0] = 'd';
+ file_type = '/';
+ }
else if(S_ISCHR(st->st_mode))
file->mode[0] = 'c';
else if(S_ISBLK(st->st_mode))
file->mode[0] = 'b';
- else if(S_ISREG(st->st_mode))
+ else if(S_ISREG(st->st_mode)) {
file->mode[0] = '-';
- else if(S_ISFIFO(st->st_mode))
+ if(st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
+ file_type = '*';
+ }
+ else if(S_ISFIFO(st->st_mode)) {
file->mode[0] = 'p';
- else if(S_ISLNK(st->st_mode))
+ file_type = '|';
+ }
+ else if(S_ISLNK(st->st_mode)) {
file->mode[0] = 'l';
- else if(S_ISSOCK(st->st_mode))
+ file_type = '@';
+ }
+ else if(S_ISSOCK(st->st_mode)) {
file->mode[0] = 's';
+ file_type = '=';
+ }
#ifdef S_ISWHT
- else if(S_ISWHT(st->st_mode))
+ else if(S_ISWHT(st->st_mode)) {
file->mode[0] = 'w';
+ file_type = '%';
+ }
#endif
else
file->mode[0] = '?';
@@ -177,9 +224,10 @@ make_fileinfo(const char *filename, struct fileinfo *file, int flags)
{
time_t t = time(NULL);
- struct tm *tm = localtime(&st->st_mtime);
- if((t - st->st_mtime > 6*30*24*60*60) ||
- (st->st_mtime - t > 6*30*24*60*60))
+ time_t mtime = st->st_mtime;
+ struct tm *tm = localtime(&mtime);
+ if((t - mtime > 6*30*24*60*60) ||
+ (mtime - t > 6*30*24*60*60))
strftime(buf, sizeof(buf), "%b %e %Y", tm);
else
strftime(buf, sizeof(buf), "%b %e %H:%M", tm);
@@ -191,7 +239,10 @@ make_fileinfo(const char *filename, struct fileinfo *file, int flags)
p++;
else
p = filename;
- file->filename = strdup(p);
+ if((flags & LS_TYPE) && file_type != 0)
+ asprintf(&file->filename, "%s%c", p, file_type);
+ else
+ file->filename = strdup(p);
}
if(S_ISLNK(st->st_mode)) {
int n;
@@ -267,7 +318,7 @@ compare_mtime(struct fileinfo *a, struct fileinfo *b)
return 1;
if(b->filename == NULL)
return -1;
- return a->st.st_mtime - b->st.st_mtime;
+ return b->st.st_mtime - a->st.st_mtime;
}
static int
@@ -277,7 +328,7 @@ compare_size(struct fileinfo *a, struct fileinfo *b)
return 1;
if(b->filename == NULL)
return -1;
- return a->st.st_size - b->st.st_size;
+ return b->st.st_size - a->st.st_size;
}
static void
@@ -299,16 +350,22 @@ log10(int num)
* have to fetch them.
*/
+#ifdef KRB4
+static int do_the_afs_dance = 1;
+#endif
+
static int
lstat_file (const char *file, struct stat *sb)
{
#ifdef KRB4
- if (k_hasafs()
+ if (do_the_afs_dance &&
+ k_hasafs()
&& strcmp(file, ".")
- && strcmp(file, ".."))
+ && strcmp(file, "..")
+ && strcmp(file, "/"))
{
struct ViceIoctl a_params;
- char *last;
+ char *dir, *last;
char *path_bkp;
static ino_t ino_counter = 0, ino_last = 0;
int ret;
@@ -328,16 +385,28 @@ lstat_file (const char *file, struct stat *sb)
last = strrchr (path_bkp, '/');
if (last != NULL) {
- *last = '\0';
- a_params.in = last + 1;
- } else
- a_params.in = (char *)file;
+ if(last[1] == '\0')
+ /* if path ended in /, replace with `.' */
+ a_params.in = ".";
+ else
+ a_params.in = last + 1;
+ while(last > path_bkp && *--last == '/');
+ if(*last != '/' || last != path_bkp) {
+ *++last = '\0';
+ dir = path_bkp;
+ } else
+ /* we got to the start, so this must be the root dir */
+ dir = "/";
+ } else {
+ /* file is relative to cdir */
+ dir = ".";
+ a_params.in = path_bkp;
+ }
a_params.in_size = strlen (a_params.in) + 1;
a_params.out_size = maxsize;
- ret = k_pioctl (last ? path_bkp : "." ,
- VIOC_AFS_STAT_MT_PT, &a_params, 0);
+ ret = k_pioctl (dir, VIOC_AFS_STAT_MT_PT, &a_params, 0);
free (a_params.out);
if (ret < 0) {
free (path_bkp);
@@ -354,7 +423,7 @@ lstat_file (const char *file, struct stat *sb)
* use . as a prototype
*/
- ret = lstat (path_bkp, sb);
+ ret = lstat (dir, sb);
free (path_bkp);
if (ret < 0)
return ret;
@@ -413,7 +482,7 @@ list_files(FILE *out, const char **files, int n_files, int flags)
(int (*)(const void*, const void*))compare_size);
break;
}
- {
+ if(DISP_MODE(flags) == LS_DISP_LONG) {
int max_inode = 0;
int max_bsize = 0;
int max_n_link = 0;
@@ -481,10 +550,58 @@ list_files(FILE *out, const char **files, int n_files, int flags)
max_major,
max_minor,
max_date);
- for(i = 0; i < n_files; i++)
- free_fileinfo(&fi[i]);
- free(fi);
+ } else if(DISP_MODE(flags) == LS_DISP_COLUMN ||
+ DISP_MODE(flags) == LS_DISP_CROSS) {
+ int max_len = 0;
+ int num_files = n_files;
+ int columns;
+ int j;
+ for(i = 0; i < n_files; i++) {
+ if(fi[i].filename == NULL) {
+ num_files--;
+ continue;
+ }
+ if(strlen(fi[i].filename) > max_len)
+ max_len = strlen(fi[i].filename);
+ }
+ columns = 80 / (max_len + 1); /* get space between columns */
+ max_len = 80 / columns;
+ if(DISP_MODE(flags) == LS_DISP_CROSS) {
+ for(i = 0, j = 0; i < n_files; i++) {
+ if(fi[i].filename == NULL)
+ continue;
+ sec_fprintf2(out, "%-*s", max_len, fi[i].filename);
+ j++;
+ if(j == columns) {
+ sec_fprintf2(out, "\r\n");
+ j = 0;
+ }
+ }
+ if(j > 0)
+ sec_fprintf2(out, "\r\n");
+ } else {
+ int skip = (num_files + columns - 1) / columns;
+ j = 0;
+ for(i = 0; i < skip; i++) {
+ for(j = i; j < n_files;) {
+ while(j < n_files && fi[j].filename == NULL)
+ j++;
+ sec_fprintf2(out, "%-*s", max_len, fi[j].filename);
+ j += skip;
+ }
+ sec_fprintf2(out, "\r\n");
+ }
+ }
+ } else {
+ for(i = 0; i < n_files; i++) {
+ if(fi[i].filename == NULL)
+ continue;
+ sec_fprintf2(out, "%s\r\n", fi[i].filename);
+ }
}
+ for(i = 0; i < n_files; i++)
+ free_fileinfo(&fi[i]);
+ free(fi);
}
static void
@@ -544,17 +661,21 @@ list_dir(FILE *out, const char *directory, int flags)
void
builtin_ls(FILE *out, const char *file)
{
- int flags = LS_SORT_NAME;
+ int flags = LS_SORT_NAME | LS_IGNORE_DOT | LS_DISP_LONG;
if(*file == '-') {
const char *p;
for(p = file + 1; *p; p++) {
switch(*p) {
+ case '1':
+ flags = (flags & ~LS_DISP_MODE);
+ break;
case 'a':
case 'A':
flags &= ~LS_IGNORE_DOT;
break;
case 'C':
+ flags = (flags & ~LS_DISP_MODE) | LS_DISP_COLUMN;
break;
case 'd':
flags |= LS_DIRS;
@@ -562,10 +683,14 @@ builtin_ls(FILE *out, const char *file)
case 'f':
flags = (flags & ~LS_SORT_MODE);
break;
+ case 'F':
+ flags |= LS_TYPE;
+ break;
case 'i':
- flags |= flags | LS_INODE;
+ flags |= LS_INODE;
break;
case 'l':
+ flags = (flags & ~LS_DISP_MODE) | LS_DISP_LONG;
break;
case 't':
flags = (flags & ~LS_SORT_MODE) | LS_SORT_MTIME;
@@ -579,6 +704,9 @@ builtin_ls(FILE *out, const char *file)
case 'r':
flags |= LS_SORT_REVERSE;
break;
+ case 'x':
+ flags = (flags & ~LS_DISP_MODE) | LS_DISP_CROSS;
+ break;
}
}
file = ".";
OpenPOWER on IntegriCloud