diff options
Diffstat (limited to 'crypto/kerberosIV/appl/ftp/ftpd')
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/Makefile.am | 3 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/Makefile.in | 6 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/extern.h | 16 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y | 134 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h | 16 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c | 9 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/kauth.c | 25 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c | 9 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/ls.c | 572 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/ftp/ftpd/popen.c | 6 |
10 files changed, 702 insertions, 94 deletions
diff --git a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am index 187fca3..282cb3a 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am +++ b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.19 1999/04/25 13:24:55 assar Exp $ +# $Id: Makefile.am,v 1.20 1999/10/03 16:38:53 joda Exp $ include $(top_srcdir)/Makefile.am.common @@ -21,6 +21,7 @@ ftpd_SOURCES = \ ftpd.c \ ftpd_locl.h \ logwtmp.c \ + ls.c \ pathnames.h \ popen.c \ security.c \ diff --git a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in index 3b555a6..bc5c12e 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in +++ b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.40 1999/03/10 19:01:11 joda Exp $ +# $Id: Makefile.in,v 1.41 1999/10/03 16:39:27 joda Exp $ # srcdir = @srcdir@ @@ -47,8 +47,8 @@ LIBROKEN= -L$(LIBTOP)/roken -lroken PROGS = ftpd$(EXECSUFFIX) -ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c popen.c security.c krb4.c kauth.c -ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o security.o krb4.o kauth.o +ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c ls.c popen.c security.c krb4.c kauth.c +ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o ls.o popen.o security.o krb4.o kauth.o SOURCES = $(ftpd_SOURCES) OBJECTS = $(ftpd_OBJS) diff --git a/crypto/kerberosIV/appl/ftp/ftpd/extern.h b/crypto/kerberosIV/appl/ftp/ftpd/extern.h index e96809e..2e1e0d0 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/extern.h +++ b/crypto/kerberosIV/appl/ftp/ftpd/extern.h @@ -67,6 +67,8 @@ char **copyblk(char **); void cwd(char *); void do_delete(char *); void dologout(int); +void eprt(char *); +void epsv(char *); void fatal(char *); int filename_check(char *); int ftpd_pclose(FILE *); @@ -86,8 +88,8 @@ __attribute__ ((format (printf, 1, 2))) #endif ; void pass(char *); -void passive(void); -void perror_reply(int, char *); +void pasv(void); +void perror_reply(int, const char *); void pwd(void); void removedir(char *); void renamecmd(char *, char *); @@ -97,7 +99,7 @@ void reply(int, const char *, ...) __attribute__ ((format (printf, 2, 3))) #endif ; -void retrieve(char *, char *); +void retrieve(const char *, char *); void send_file_list(char *); void setproctitle(const char *, ...) #ifdef __GNUC__ @@ -111,6 +113,8 @@ void upper(char *); void user(char *); void yyerror(char *); +void list_file(char*); + void kauth(char *, char*); void klist(void); void cond_kdestroy(void); @@ -121,15 +125,17 @@ void afsunlog(void); int find(char *); +void builtin_ls(FILE*, const char*); + int do_login(int code, char *passwd); int klogin(char *name, char *password); const char *ftp_rooted(const char *path); -extern struct sockaddr_in ctrl_addr, his_addr; +extern struct sockaddr *ctrl_addr, *his_addr; extern char hostname[]; -extern struct sockaddr_in data_dest; +extern struct sockaddr *data_dest; extern int logged_in; extern struct passwd *pw; extern int guest; diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y b/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y index be36ea2..07ff9a5 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y +++ b/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y @@ -43,7 +43,7 @@ %{ #include "ftpd_locl.h" -RCSID("$Id: ftpcmd.y,v 1.48 1999/05/08 02:22:43 assar Exp $"); +RCSID("$Id: ftpcmd.y,v 1.56 1999/10/26 11:56:23 assar Exp $"); off_t restart_point; @@ -98,6 +98,7 @@ static int yylex (void); ABOR DELE CWD LIST NLST SITE sTAT HELP NOOP MKD RMD PWD CDUP STOU SMNT SYST SIZE MDTM + EPRT EPSV UMASK IDLE CHMOD @@ -105,7 +106,9 @@ static int yylex (void); CONF ENC KAUTH KLIST KDESTROY KRBTKFILE AFSLOG - FIND URL + LOCATE URL + + FEAT OPTS LEXERR @@ -151,9 +154,23 @@ cmd } reply(200, "PORT command successful."); } + | EPRT SP STRING CRLF + { + eprt ($3); + free ($3); + } | PASV CRLF { - passive(); + pasv (); + } + | EPSV CRLF + { + epsv (NULL); + } + | EPSV SP STRING CRLF + { + epsv ($3); + free ($3); } | TYPE SP type_code CRLF { @@ -224,24 +241,30 @@ cmd } | RETR SP pathname CRLF check_login { - if ($5 && $3 != NULL) - retrieve(0, $3); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + retrieve(0, name); + if (name != NULL) + free(name); } | STOR SP pathname CRLF check_login { - if ($5 && $3 != NULL) - do_store($3, "w", 0); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + do_store(name, "w", 0); + if (name != NULL) + free(name); } | APPE SP pathname CRLF check_login { - if ($5 && $3 != NULL) - do_store($3, "a", 0); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + do_store(name, "a", 0); + if (name != NULL) + free(name); } | NLST CRLF check_login { @@ -250,33 +273,23 @@ cmd } | NLST SP STRING CRLF check_login { - if ($5 && $3 != NULL) - send_file_list($3); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + send_file_list(name); + if (name != NULL) + free(name); } | LIST CRLF check_login { -#ifdef HAVE_LS_A - char *cmd = "/bin/ls -lA"; -#else - char *cmd = "/bin/ls -la"; -#endif - if ($3) - retrieve(cmd, ""); - + if($3) + list_file("."); } | LIST SP pathname CRLF check_login { -#ifdef HAVE_LS_A - char *cmd = "/bin/ls -lA %s"; -#else - char *cmd = "/bin/ls -la %s"; -#endif - if ($5 && $3 != NULL) - retrieve(cmd, $3); - if ($3 != NULL) - free($3); + if($5) + list_file($3); + free($3); } | sTAT SP pathname CRLF check_login { @@ -388,6 +401,20 @@ cmd if ($3) cwd(".."); } + | FEAT CRLF + { + lreply(211, "Supported features:"); + lreply(0, " MDTM"); + lreply(0, " REST STREAM"); + lreply(0, " SIZE"); + reply(211, "End"); + } + | OPTS SP STRING CRLF + { + free ($3); + reply(501, "Bad options"); + } + | SITE SP HELP CRLF { help(sitetab, (char *) 0); @@ -522,16 +549,15 @@ cmd #ifdef KRB4 if(guest) reply(500, "Can't be done as guest."); - else if($7){ + else if($7) afslog($5); - } if($5) free($5); #else reply(500, "Command not implemented."); #endif } - | SITE SP FIND SP STRING CRLF check_login + | SITE SP LOCATE SP STRING CRLF check_login { if($7 && $5 != NULL) find($5); @@ -696,9 +722,11 @@ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER { - data_dest.sin_family = AF_INET; - data_dest.sin_port = htons($9 * 256 + $11); - data_dest.sin_addr.s_addr = + struct sockaddr_in *sin = (struct sockaddr_in *)data_dest; + + sin->sin_family = AF_INET; + sin->sin_port = htons($9 * 256 + $11); + sin->sin_addr.s_addr = htonl(($1 << 24) | ($3 << 16) | ($5 << 8) | $7); } ; @@ -901,7 +929,9 @@ struct tab cmdtab[] = { /* In order defined in RFC 765 */ { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, + { "EPRT", EPRT, STR1, 1, "<sp> string" }, { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, + { "EPSV", EPSV, OSTR, 1, "[<sp> foo]" }, { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, { "STRU", STRU, ARGS, 1, "(specify file structure)" }, { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, @@ -952,6 +982,10 @@ struct tab cmdtab[] = { /* In order defined in RFC 765 */ { "CONF", CONF, STR1, 1, "<sp> confidentiality command" }, { "ENC", ENC, STR1, 1, "<sp> privacy command" }, + /* RFC2389 */ + { "FEAT", FEAT, ARGS, 1, "" }, + { "OPTS", OPTS, ARGS, 1, "<sp> command [<sp> options]" }, + { NULL, 0, 0, 0, 0 } }; @@ -967,7 +1001,8 @@ struct tab sitetab[] = { { "KRBTKFILE", KRBTKFILE, STR1, 1, "<sp> ticket-file" }, { "AFSLOG", AFSLOG, OSTR, 1, "[<sp> cell]" }, - { "FIND", FIND, STR1, 1, "<sp> globexpr" }, + { "LOCATE", LOCATE, STR1, 1, "<sp> globexpr" }, + { "FIND", LOCATE, STR1, 1, "<sp> globexpr" }, { "URL", URL, ARGS, 1, "?" }, @@ -996,7 +1031,7 @@ ftpd_getline(char *s, int n) cs = s; /* tmpline may contain saved command from urgent mode interruption */ if(ftp_command){ - strcpy_truncate(s, ftp_command, n); + strlcpy(s, ftp_command, n); if (debug) syslog(LOG_DEBUG, "command: %s", s); #ifdef XXX @@ -1162,7 +1197,10 @@ yylex(void) dostr1: if (cbuf[cpos] == ' ') { cpos++; - state = state == OSTR ? STR2 : ++state; + if(state == OSTR) + state = STR2; + else + state++; return (SP); } break; @@ -1335,7 +1373,7 @@ help(struct tab *ctab, char *s) columns = 1; lines = (NCMDS + columns - 1) / columns; for (i = 0; i < lines; i++) { - strcpy_truncate (buf, " ", sizeof(buf)); + strlcpy (buf, " ", sizeof(buf)); for (j = 0; j < columns; j++) { c = ctab + j * lines + i; snprintf (buf + strlen(buf), @@ -1347,13 +1385,13 @@ help(struct tab *ctab, char *s) break; w = strlen(c->name) + 1; while (w < width) { - strcat_truncate (buf, + strlcat (buf, " ", sizeof(buf)); w++; } } - lreply(214, buf); + lreply(214, "%s", buf); } reply(214, "Direct comments to kth-krb-bugs@pdc.kth.se"); return; diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h b/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h index 4bb3ad3..5cb4904 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h +++ b/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: ftpd_locl.h,v 1.5.2.1 1999/07/22 03:24:42 assar Exp $ */ +/* $Id: ftpd_locl.h,v 1.9 1999/12/02 16:58:30 joda Exp $ */ #ifndef __ftpd_locl_h__ #define __ftpd_locl_h__ @@ -63,6 +58,9 @@ #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include <sys/ioctl.h> #endif +#ifdef HAVE_SYS_IOCCOM_H +#include <sys/ioccom.h> +#endif #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> @@ -159,6 +157,10 @@ extern int LIBPREFIX(fclose) (FILE *); #endif +/* SunOS doesn't have any declaration of fclose */ + +int fclose(FILE *stream); + int yyparse(); #ifndef LOG_FTP diff --git a/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c b/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c index 8a1a8e3..28e3596 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -40,7 +35,7 @@ #include <gssapi.h> #include <krb5.h> -RCSID("$Id: gss_userok.c,v 1.1 1998/05/12 12:15:22 joda Exp $"); +RCSID("$Id: gss_userok.c,v 1.2 1999/12/02 16:58:31 joda Exp $"); /* XXX a bit too much of krb5 dependency here... What is the correct way to do this? diff --git a/crypto/kerberosIV/appl/ftp/ftpd/kauth.c b/crypto/kerberosIV/appl/ftp/ftpd/kauth.c index 33795b6..dad4de5 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/kauth.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/kauth.c @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #include "ftpd_locl.h" -RCSID("$Id: kauth.c,v 1.22 1999/06/29 21:19:33 bg Exp $"); +RCSID("$Id: kauth.c,v 1.25 1999/12/02 16:58:31 joda Exp $"); static KTEXT_ST cip; static unsigned int lifetime; @@ -85,7 +80,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's name */ - strcpy_truncate(sp.name, ptr, sizeof(sp.name)); + strlcpy(sp.name, ptr, sizeof(sp.name)); ptr += len + 1; left -= len + 1; @@ -94,7 +89,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's instance */ - strcpy_truncate(sp.instance, ptr, sizeof(sp.instance)); + strlcpy(sp.instance, ptr, sizeof(sp.instance)); ptr += len + 1; left -= len + 1; @@ -103,7 +98,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's realm */ - strcpy_truncate(sp.realm, ptr, sizeof(sp.realm)); + strlcpy(sp.realm, ptr, sizeof(sp.realm)); ptr += len + 1; left -= len + 1; @@ -176,6 +171,10 @@ kauth(char *principal, char *ticket) char *p; int ret; + if(get_command_prot() != prot_private) { + reply(500, "Request denied (bad protection level)"); + return; + } ret = krb_parse_name(principal, &pr); if(ret){ reply(500, "Bad principal: %s.", krb_get_err_text(ret)); @@ -304,12 +303,12 @@ klist(void) " Issued", " Expires", " Principal (kvno)"); header = 0; } - strcpy_truncate(buf1, short_date(c.issue_date), sizeof(buf1)); + strlcpy(buf1, short_date(c.issue_date), sizeof(buf1)); c.issue_date = krb_life_to_time(c.issue_date, c.lifetime); if (time(0) < (unsigned long) c.issue_date) - strcpy_truncate(buf2, short_date(c.issue_date), sizeof(buf2)); + strlcpy(buf2, short_date(c.issue_date), sizeof(buf2)); else - strcpy_truncate(buf2, ">>> Expired <<< ", sizeof(buf2)); + strlcpy(buf2, ">>> Expired <<< ", sizeof(buf2)); lreply(200, "%s %s %s (%d)", buf1, buf2, krb_unparse_name_long(c.service, c.instance, c.realm), c.kvno); } diff --git a/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c b/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c index d948a5a..019cc2d 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: logwtmp.c,v 1.13 1999/03/01 09:49:37 joda Exp $"); +RCSID("$Id: logwtmp.c,v 1.14 1999/12/02 16:58:31 joda Exp $"); #endif #include <stdio.h> diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ls.c b/crypto/kerberosIV/appl/ftp/ftpd/ls.c new file mode 100644 index 0000000..97eb77e --- /dev/null +++ b/crypto/kerberosIV/appl/ftp/ftpd/ls.c @@ -0,0 +1,572 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "ftpd_locl.h" + +RCSID("$Id: ls.c,v 1.13 1999/11/20 20:49:41 assar Exp $"); + +struct fileinfo { + struct stat st; + int inode; + int bsize; + char mode[11]; + int n_link; + char *user; + char *group; + char *size; + char *major; + char *minor; + char *date; + char *filename; + char *link; +}; + +#define LS_DIRS 1 +#define LS_IGNORE_DOT 2 +#define LS_SORT_MODE 12 +#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 + +#ifndef S_ISTXT +#define S_ISTXT S_ISVTX +#endif + +#ifndef S_ISSOCK +#define S_ISSOCK(mode) (((mode) & _S_IFMT) == S_IFSOCK) +#endif + +#ifndef S_ISLNK +#define S_ISLNK(mode) (((mode) & _S_IFMT) == S_IFLNK) +#endif + +static void +make_fileinfo(const char *filename, struct fileinfo *file, int flags) +{ + char buf[128]; + struct stat *st = &file->st; + + file->inode = st->st_ino; +#ifdef S_BLKSIZE + file->bsize = st->st_blocks * S_BLKSIZE / 1024; +#else + file->bsize = st->st_blocks * 512 / 1024; +#endif + + if(S_ISDIR(st->st_mode)) + file->mode[0] = 'd'; + 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)) + file->mode[0] = '-'; + else if(S_ISFIFO(st->st_mode)) + file->mode[0] = 'p'; + else if(S_ISLNK(st->st_mode)) + file->mode[0] = 'l'; + else if(S_ISSOCK(st->st_mode)) + file->mode[0] = 's'; +#ifdef S_ISWHT + else if(S_ISWHT(st->st_mode)) + file->mode[0] = 'w'; +#endif + else + file->mode[0] = '?'; + { + char *x[] = { "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" }; + strcpy(file->mode + 1, x[(st->st_mode & S_IRWXU) >> 6]); + strcpy(file->mode + 4, x[(st->st_mode & S_IRWXG) >> 3]); + strcpy(file->mode + 7, x[(st->st_mode & S_IRWXO) >> 0]); + if((st->st_mode & S_ISUID)) { + if((st->st_mode & S_IXUSR)) + file->mode[3] = 's'; + else + file->mode[3] = 'S'; + } + if((st->st_mode & S_ISGID)) { + if((st->st_mode & S_IXGRP)) + file->mode[6] = 's'; + else + file->mode[6] = 'S'; + } + if((st->st_mode & S_ISTXT)) { + if((st->st_mode & S_IXOTH)) + file->mode[9] = 't'; + else + file->mode[9] = 'T'; + } + } + file->n_link = st->st_nlink; + { + struct passwd *pwd; + pwd = getpwuid(st->st_uid); + if(pwd == NULL) + asprintf(&file->user, "%u", (unsigned)st->st_uid); + else + file->user = strdup(pwd->pw_name); + } + { + struct group *grp; + grp = getgrgid(st->st_gid); + if(grp == NULL) + asprintf(&file->group, "%u", (unsigned)st->st_gid); + else + file->group = strdup(grp->gr_name); + } + + if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) { +#if defined(major) && defined(minor) + asprintf(&file->major, "%u", (unsigned)major(st->st_rdev)); + asprintf(&file->minor, "%u", (unsigned)minor(st->st_rdev)); +#else + /* Don't want to use the DDI/DKI crap. */ + asprintf(&file->major, "%u", (unsigned)st->st_rdev); + asprintf(&file->minor, "%u", 0); +#endif + } else + asprintf(&file->size, "%lu", (unsigned long)st->st_size); + + { + 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)) + strftime(buf, sizeof(buf), "%b %e %Y", tm); + else + strftime(buf, sizeof(buf), "%b %e %H:%M", tm); + file->date = strdup(buf); + } + { + const char *p = strrchr(filename, '/'); + if(p) + p++; + else + p = filename; + file->filename = strdup(p); + } + if(S_ISLNK(st->st_mode)) { + int n; + n = readlink((char *)filename, buf, sizeof(buf)); + if(n >= 0) { + buf[n] = '\0'; + file->link = strdup(buf); + } else + warn("%s: readlink", filename); + } +} + +static void +print_file(FILE *out, + int flags, + struct fileinfo *f, + int max_inode, + int max_bsize, + int max_n_link, + int max_user, + int max_group, + int max_size, + int max_major, + int max_minor, + int max_date) +{ + if(f->filename == NULL) + return; + + if(flags & LS_INODE) { + sec_fprintf2(out, "%*d", max_inode, f->inode); + sec_fprintf2(out, " "); + } + if(flags & LS_SIZE) { + sec_fprintf2(out, "%*d", max_bsize, f->bsize); + sec_fprintf2(out, " "); + } + sec_fprintf2(out, "%s", f->mode); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%*d", max_n_link, f->n_link); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%-*s", max_user, f->user); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%-*s", max_group, f->group); + sec_fprintf2(out, " "); + if(f->major != NULL && f->minor != NULL) + sec_fprintf2(out, "%*s, %*s", max_major, f->major, max_minor, f->minor); + else + sec_fprintf2(out, "%*s", max_size, f->size); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%*s", max_date, f->date); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%s", f->filename); + if(f->link) + sec_fprintf2(out, " -> %s", f->link); + sec_fprintf2(out, "\r\n"); +} + +static int +compare_filename(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return strcmp(a->filename, b->filename); +} + +static int +compare_mtime(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return a->st.st_mtime - b->st.st_mtime; +} + +static int +compare_size(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return a->st.st_size - b->st.st_size; +} + +static void +list_dir(FILE *out, const char *directory, int flags); + +static int +log10(int num) +{ + int i = 1; + while(num > 10) { + i++; + num /= 10; + } + return i; +} + +/* + * Operate as lstat but fake up entries for AFS mount points so we don't + * have to fetch them. + */ + +static int +lstat_file (const char *file, struct stat *sb) +{ +#ifdef KRB4 + if (k_hasafs() + && strcmp(file, ".") + && strcmp(file, "..")) + { + struct ViceIoctl a_params; + char *last; + char *path_bkp; + static ino_t ino_counter = 0, ino_last = 0; + int ret; + const int maxsize = 2048; + + path_bkp = strdup (file); + if (path_bkp == NULL) + return -1; + + a_params.out = malloc (maxsize); + if (a_params.out == NULL) { + free (path_bkp); + return -1; + } + + /* If path contains more than the filename alone - split it */ + + last = strrchr (path_bkp, '/'); + if (last != NULL) { + *last = '\0'; + a_params.in = last + 1; + } else + a_params.in = (char *)file; + + 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); + free (a_params.out); + if (ret < 0) { + free (path_bkp); + + if (errno != EINVAL) + return ret; + else + /* if we get EINVAL this is probably not a mountpoint */ + return lstat (file, sb); + } + + /* + * wow this was a mountpoint, lets cook the struct stat + * use . as a prototype + */ + + ret = lstat (path_bkp, sb); + free (path_bkp); + if (ret < 0) + return ret; + + if (ino_last == sb->st_ino) + ino_counter++; + else { + ino_last = sb->st_ino; + ino_counter = 0; + } + sb->st_ino += ino_counter; + sb->st_nlink = 3; + + return 0; + } +#endif /* KRB4 */ + return lstat (file, sb); +} + +static void +list_files(FILE *out, char **files, int n_files, int flags) +{ + struct fileinfo *fi; + int i; + + fi = calloc(n_files, sizeof(*fi)); + if (fi == NULL) { + sec_fprintf2(out, "ouf of memory\r\n"); + return; + } + for(i = 0; i < n_files; i++) { + if(lstat_file(files[i], &fi[i].st) < 0) { + sec_fprintf2(out, "%s: %s\r\n", files[i], strerror(errno)); + fi[i].filename = NULL; + } else { + if((flags & LS_DIRS) == 0 && S_ISDIR(fi[i].st.st_mode)) { + if(n_files > 1) + sec_fprintf2(out, "%s:\r\n", files[i]); + list_dir(out, files[i], flags); + } else { + make_fileinfo(files[i], &fi[i], flags); + } + } + } + switch(SORT_MODE(flags)) { + case LS_SORT_NAME: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_filename); + break; + case LS_SORT_MTIME: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_mtime); + break; + case LS_SORT_SIZE: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_size); + break; + } + { + int max_inode = 0; + int max_bsize = 0; + int max_n_link = 0; + int max_user = 0; + int max_group = 0; + int max_size = 0; + int max_major = 0; + int max_minor = 0; + int max_date = 0; + for(i = 0; i < n_files; i++) { + if(fi[i].filename == NULL) + continue; + if(fi[i].inode > max_inode) + max_inode = fi[i].inode; + if(fi[i].bsize > max_bsize) + max_bsize = fi[i].bsize; + if(fi[i].n_link > max_n_link) + max_n_link = fi[i].n_link; + if(strlen(fi[i].user) > max_user) + max_user = strlen(fi[i].user); + if(strlen(fi[i].group) > max_group) + max_group = strlen(fi[i].group); + if(fi[i].major != NULL && strlen(fi[i].major) > max_major) + max_major = strlen(fi[i].major); + if(fi[i].minor != NULL && strlen(fi[i].minor) > max_minor) + max_minor = strlen(fi[i].minor); + if(fi[i].size != NULL && strlen(fi[i].size) > max_size) + max_size = strlen(fi[i].size); + if(strlen(fi[i].date) > max_date) + max_date = strlen(fi[i].date); + } + if(max_size < max_major + max_minor + 2) + max_size = max_major + max_minor + 2; + else if(max_size - max_minor - 2 > max_major) + max_major = max_size - max_minor - 2; + max_inode = log10(max_inode); + max_bsize = log10(max_bsize); + max_n_link = log10(max_n_link); + + if(flags & LS_SORT_REVERSE) + for(i = n_files - 1; i >= 0; i--) + print_file(out, + flags, + &fi[i], + max_inode, + max_bsize, + max_n_link, + max_user, + max_group, + max_size, + max_major, + max_minor, + max_date); + else + for(i = 0; i < n_files; i++) + print_file(out, + flags, + &fi[i], + max_inode, + max_bsize, + max_n_link, + max_user, + max_group, + max_size, + max_major, + max_minor, + max_date); + } +} + +static void +free_files (char **files, int n) +{ + int i; + + for (i = 0; i < n; ++i) + free (files[i]); + free (files); +} + +static void +list_dir(FILE *out, const char *directory, int flags) +{ + DIR *d = opendir(directory); + struct dirent *ent; + char **files = NULL; + int n_files = 0; + + if(d == NULL) { + sec_fprintf2(out, "%s: %s\r\n", directory, strerror(errno)); + return; + } + while((ent = readdir(d)) != NULL) { + void *tmp; + + if(ent->d_name[0] == '.') { + if (flags & LS_IGNORE_DOT) + continue; + if (ent->d_name[1] == 0) /* Ignore . */ + continue; + if (ent->d_name[1] == '.' && ent->d_name[2] == 0) /* Ignore .. */ + continue; + } + tmp = realloc(files, (n_files + 1) * sizeof(*files)); + if (tmp == NULL) { + sec_fprintf2(out, "%s: out of memory\r\n", directory); + free_files (files, n_files); + closedir (d); + return; + } + files = tmp; + asprintf(&files[n_files], "%s/%s", directory, ent->d_name); + if (files[n_files] == NULL) { + sec_fprintf2(out, "%s: out of memory\r\n", directory); + free_files (files, n_files); + closedir (d); + return; + } + ++n_files; + } + closedir(d); + list_files(out, files, n_files, flags | LS_DIRS); +} + +void +builtin_ls(FILE *out, const char *file) +{ + int flags = LS_SORT_NAME; + + if(*file == '-') { + const char *p; + for(p = file + 1; *p; p++) { + switch(*p) { + case 'a': + case 'A': + flags &= ~LS_IGNORE_DOT; + break; + case 'C': + break; + case 'd': + flags |= LS_DIRS; + break; + case 'f': + flags = (flags & ~LS_SORT_MODE); + break; + case 'i': + flags |= flags | LS_INODE; + break; + case 'l': + break; + case 't': + flags = (flags & ~LS_SORT_MODE) | LS_SORT_MTIME; + break; + case 's': + flags |= LS_SIZE; + break; + case 'S': + flags = (flags & ~LS_SORT_MODE) | LS_SORT_SIZE; + break; + case 'r': + flags |= LS_SORT_REVERSE; + break; + } + } + file = "."; + } + list_files(out, &file, 1, flags); + sec_fflush(out); +} diff --git a/crypto/kerberosIV/appl/ftp/ftpd/popen.c b/crypto/kerberosIV/appl/ftp/ftpd/popen.c index 4bd5e04..5f36813 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/popen.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/popen.c @@ -37,7 +37,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: popen.c,v 1.18 1998/06/09 19:24:24 joda Exp $"); +RCSID("$Id: popen.c,v 1.19 1999/09/16 20:38:45 assar Exp $"); #endif #include <sys/types.h> @@ -89,10 +89,10 @@ ftp_rooted(const char *path) if(!home[0]) if((pwd = k_getpwnam("ftp"))) - strcpy_truncate(home, pwd->pw_dir, sizeof(home)); + strlcpy(home, pwd->pw_dir, sizeof(home)); snprintf(newpath, sizeof(newpath), "%s/%s", home, path); if(access(newpath, X_OK)) - strcpy_truncate(newpath, path, sizeof(newpath)); + strlcpy(newpath, path, sizeof(newpath)); return newpath; } |