summaryrefslogtreecommitdiff
path: root/libc/tests/ft.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/tests/ft.c')
-rw-r--r--libc/tests/ft.c1209
1 files changed, 0 insertions, 1209 deletions
diff --git a/libc/tests/ft.c b/libc/tests/ft.c
deleted file mode 100644
index 1bdc737..0000000
--- a/libc/tests/ft.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
- * This program is distributed under the GNU General Public License.
- */
-
-/*
- * File Tool, This program is a collection of basic file tools
- * it includes cat, cp, ln, mkdir, mknod, chmod, chown, mv, rm
- *
- * Links may be used to call it under any of these names.
- */
-#include <stdio.h>
-#ifdef __STDC__
-#include <unistd.h>
-#include <stdlib.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/param.h>
-#include <utime.h>
-#include <pwd.h>
-#include <grp.h>
-
-#ifdef S_IFSOCK
-#include <sys/socket.h>
-#endif
-#ifndef S_IFLNK
-#define lstat stat
-#endif
-
-/* Ansi prototypes */
-#ifdef __STTDC__
-#define PR(x) x
-#else
-#define PR(x) ()
-#endif
-
-void main PR((int argc, char ** argv));
-int select_command PR((char * argv));
-void do_prep PR((void));
-void do_post PR((void));
-void execute PR((char * dname, char * fname));
-int exec_for_subdir PR((char * dname));
-void exec_for_item PR((int when, char * fname));
-void parse_perms PR((char * prefix, char * ustring));
-int edit_mode PR((int mode, char * mode_str));
-int cmd_ft PR((char * fname));
-int cmd_mkfifo PR((char * fname));
-int cmd_mksock PR((char * fname));
-int cmd_rm PR((char * fname));
-void build_dest PR((char * dest, char * name, char * newpath));
-int strisdigit PR((char * str));
-int cmd_mv PR((char * fname));
-int cmd_ln PR((char * fname));
-int cmd_cp PR((char * fname));
-int copy_modes PR((char * file));
-int copy_file PR((char * source, char * dest));
-void Usage PR((void));
-int cmd_mkdir PR((char * dirname));
-int cmd_mknod PR((void));
-int warning PR((int enumber, char * estr, char * eobj));
-int error PR((int enumber, char * estr, char * eobj));
-
-#define DO_BDIR 0x0010 /* Do Dir before contents */
-#define DO_ADIR 0x0020 /* Do Dir after contents */
-#define DO_MCOPY 0x0040 /* Preserve modes flag forced */
-#define OK_DIR 0x0080 /* Directorys OK even if no flg_recurse */
-#define IGN_LNK 0x0100 /* Not interested in symlinks */
-#define NO_SOURCE 0x0200 /* Named files created */
-#define OK_NO_SOURCE 0x0400 /* Don't need the source */
-
-#define CMD_FT (0+OK_DIR+DO_BDIR)
-#define CMD_CAT (1+IGN_LNK)
-#define CMD_CHGRP (2+OK_DIR+IGN_LNK+DO_ADIR)
-#define CMD_CHMOD (3+OK_DIR+IGN_LNK+DO_ADIR)
-#define CMD_CHOWN (4+OK_DIR+IGN_LNK+DO_ADIR)
-#define CMD_CP (5+IGN_LNK)
-#define CMD_EXTAR (6+DO_MCOPY+DO_BDIR)
-#define CMD_INSTALL (7+DO_MCOPY)
-#define CMD_LN (8+IGN_LNK+DO_BDIR)
-#define CMD_MKDIR (9+NO_SOURCE)
-#define CMD_MKFIFO (10+NO_SOURCE)
-#define CMD_MKSOCK (11+NO_SOURCE)
-#define CMD_MKNOD (12+NO_SOURCE)
-#define CMD_MV (13+DO_MCOPY+OK_DIR+DO_BDIR)
-#define CMD_RM (14+DO_ADIR)
-
-struct {
- char * name;
- int cmd;
- int argpat;
- char * opts;
-} command_list[] =
-{
- { "ft", CMD_FT, 0, "-Rv" },
- { "cat", CMD_CAT, 0, "uR" },
- { "chgrp", CMD_CHGRP, 1, "vfR" },
- { "chmod", CMD_CHMOD, 1, "vfR" },
- { "chown", CMD_CHOWN, 1, "vfR" },
- { "cp", CMD_CP, -1, "vifRrpsda" },
- { "extar", CMD_EXTAR, 1, "" },
- { "install", CMD_INSTALL, -1, "cdso:g:m:" },
- { "ln", CMD_LN, -1, "vifs" },
- { "mkdir", CMD_MKDIR, 0, "m:" },
- { "mkfifo", CMD_MKFIFO, 0, "m:" },
-#ifdef S_IFSOCK
- { "mksock", CMD_MKSOCK, 0, "m:" },
-#endif
- { "mknod", CMD_MKNOD, 4, "m:" },
- { "mv", CMD_MV, -1, "vif" },
- { "rm", CMD_RM, 0, "vifr" },
- { 0 }
-};
-
-int cmd_arg = 0;
-int cmd_tok = CMD_FT;
-char * cmd_opt = "-";
-char * cmd_string = 0; /* the first (or last) arg where special */
-char * prog_name = "";
-
-char ** flist = 0;
-int fcount = 0;
-int add_base=0;
-char * or_name = 0;
-int or_offset = 0;
-
-int flg_recurse = 0;
-int flg_verbose = 1;
-int flg_preserve= 0;
-int flg_mkpdir = 0;
-int flg_noderef = 0;
-int flg_symlink = 0;
-int flg_exestrip= 0;
-
-int flg_r, flg_force;
-char *str_o, *str_g, *str_m;
-
-/* Things to set on the new file */
-int set_user = -1;
-int set_group = -1;
-int set_mode = -1;
-time_t set_time = -1;
-char mode_str[32] = "";
-int u_mask = 0; /* 07777 altered by umask() */
-
-struct stat cur_file_stat;
-struct stat dest_item;
-struct stat access_stat;
-
-int done_something = 0;
-
-void
-main(argc, argv)
-int argc; char ** argv;
-{
- int ar;
- (void) select_command(argv[0]);
-
- for(ar=1;
- argv[ar] && argv[ar][0] == '-' && argv[ar][1];
- ar++)
- {
- char * p = argv[ar]+1;
- /* For symbolic changes of the form -rwx */
- if( cmd_tok == CMD_CHMOD && strchr("rwx", *p) != 0 ) break;
- while(*p)
- {
- char * ap=0, *av=0;
- char ch;
- /* Is it a valid opt for this cmd */
- if(*p == ':' || (ap=strchr(cmd_opt, *p)) == 0) Usage();
-
- /* Got an argument ? */
- if(ap[1] == ':')
- {
- if(!argv[ar+1]) Usage();
- av = argv[++ar];
- }
-
- if( (ch = *p) == '-' )
- {
- if( (ch=select_command(p)) < 0 ) Usage();
- }
- switch(ch)
- {
- case '\0': break;
- case 'r':
- case 'R': flg_recurse++; break;
- case 'v': flg_verbose++; break;
- case 'p': if(cmd_tok == CMD_MKDIR) flg_mkpdir++;
- else flg_preserve++;
- break;
- case 'd': if(cmd_tok == CMD_INSTALL)
- { flg_mkpdir++; cmd_arg=0; } /* Special mkdir */
- else flg_noderef++; /* cmd_copy */
- break;
-
- case 'f': flg_force++; flg_verbose=0; break;
- case 'o': str_o = av; break;
- case 'g': str_g = av; break;
- case 'm': str_m = av; break;
-
- case 's': flg_symlink++;
- if( cmd_tok == CMD_LN) cmd_tok |= OK_DIR+OK_NO_SOURCE;
- break;
- case 'a': flg_recurse++; flg_preserve++; flg_noderef++;
- break;
- }
- if(*p == '-') break;
- p++;
- }
- }
-
- switch(cmd_arg)
- {
- case 1:
- if( ar >= argc ) Usage();
- cmd_string = argv[ar++];
- fcount = argc-ar;
- flist = argv+ar;
- break;
- case 0:
- fcount = argc-ar;
- flist = argv+ar;
- break;
- case -1:
- if( ar >= argc ) Usage();
- cmd_string = argv[argc-1];
- fcount = argc-ar-1;
- flist = argv+ar;
- break;
- default:
- if( ar != argc-cmd_arg ) Usage();
- fcount = argc-ar;
- flist = argv+ar;
- break;
- }
-
- do_prep();
-
- for(ar=0; ar<fcount; ar++)
- {
- done_something=1;
- or_name = flist[ar]; or_offset = strlen(or_name)+1;
- execute(flist[ar], (char*)0);
- }
-
- do_post();
-
- if( !done_something )
- {
- if( cmd_tok == CMD_CAT )
- execute("-", (char*)0);
- else
- Usage();
- }
- exit(0);
-}
-
-int select_command(argv)
-char * argv;
-{
- int ar;
- char *p, *s;
- prog_name = argv;
- for(ar=0; command_list[ar].name; ar++)
- {
- p = strrchr(argv, '-'); if(p) p++; else p=argv;
- s = strrchr(p, '/'); if(s) s++; else s=p;
- if( strcmp(s, command_list[ar].name) == 0 )
- {
- cmd_arg = command_list[ar].argpat;
- cmd_tok = command_list[ar].cmd;
- cmd_opt = command_list[ar].opts;
- return 0;
- }
- }
- return -1;
-}
-
-void do_prep()
-{
- char * prefix = "::";
-
- u_mask = umask(077);
- umask(u_mask);
- u_mask = (07777&(~u_mask));
-
- if(cmd_tok&DO_MCOPY) flg_preserve++;
- if(str_m) parse_perms(prefix, str_m);
-
- switch(cmd_tok)
- {
- /* mknod is very different */
- case CMD_MKNOD: cmd_mknod(); exit(0); break;
-
- case CMD_CP:
- if(strcmp(cmd_string, "-") == 0)
- {
- cmd_tok = CMD_CAT;
- cmd_arg = 0;
- break;
- }
- if(flg_symlink)
- {
- cmd_tok = CMD_LN+OK_DIR+OK_NO_SOURCE;
- flg_preserve = 0;
- }
- break;
-
- case CMD_CHOWN: prefix++;
- case CMD_CHGRP: prefix++;
- case CMD_CHMOD:
- parse_perms(prefix, cmd_string);
- set_time = 0;
- break;
- case CMD_INSTALL:
- flg_exestrip = flg_symlink;
- flg_symlink = 0;
- if(str_o) parse_perms(prefix+2, str_o);
- if(str_g) parse_perms(prefix+1, str_g);
- if(flg_mkpdir) cmd_tok = CMD_MKDIR;
- else
- {
- cmd_tok = CMD_CP;
- flg_preserve = 1;
- }
- break;
- }
-
-#ifndef S_IFLNK
- if(flg_symlink)
- {
- error(0, "No support for symlinks available:", cmd_string);
- exit(1);
- }
-#endif
-
- /* Are we transfering many to one ? Then it must be a directory */
- if(cmd_arg == -1)
- {
- if( stat(cmd_string, &dest_item) == -1)
- {
- if( fcount > 1 )
- {
- if( cmd_mkdir(cmd_string) < 0 )
- exit(1);
- stat(cmd_string, &dest_item);
- add_base = 1;
- }
- }
- else
- {
- if( !S_ISDIR(dest_item.st_mode) )
- {
- if( fcount > 1 )
- {
- error(0, "Destination must be a directory:", cmd_string);
- exit(1);
- }
- }
- else add_base = 1;
- }
- }
-}
-
-void do_post()
-{
- /* Oh! It seems there's nothing to do, ah well. */
-}
-
-void execute(dname, fname)
-char * dname; char * fname;
-{
- char * buf;
- if( strcmp(dname, "-") == 0 )
- {
- exec_for_item(0, dname);
- return;
- }
- if( fname )
- {
- buf = alloca(strlen(dname) + strlen(fname) + 4);
- if( buf == 0 )
- {
- error(errno, "Can't allocate memory for path beyond ", dname);
- return ;
- }
- strcpy(buf, dname);
- if(strcmp(dname, "/")) strcat(buf, "/");
- strcat(buf, fname);
- }
- else buf = dname;
-
- if( lstat(buf, &cur_file_stat) == -1 )
- {
- if( cmd_tok&(NO_SOURCE|OK_NO_SOURCE) )
- exec_for_item(0, buf);
- else
- warning(errno, "", buf);
- return;
- }
- if( !flg_force && ( cmd_tok&NO_SOURCE ))
- {
- error(EEXIST, "", buf);
- return;
- }
-
- if( S_ISDIR(cur_file_stat.st_mode))
- {
- if( (cmd_tok&OK_DIR) || flg_recurse )
- (void) exec_for_subdir(buf);
- else
- error(EISDIR, "", buf);
- return;
- }
-
-#ifdef S_IFLNK
- if( S_ISLNK(cur_file_stat.st_mode))
- {
- /* Links are special */
- if( cmd_tok&IGN_LNK )
- {
- if( stat(buf, &cur_file_stat) == -1 )
- {
- warning(errno, "", buf);
- return;
- }
- }
- }
-#endif
- exec_for_item(0, buf);
-}
-
-int exec_for_subdir(dname)
-char * dname;
-{
- DIR * dfd;
- struct dirent * ent;
- int old_mode = -1;
-
- if( cmd_tok&DO_BDIR ) exec_for_item(-1, dname);
-
- if( flg_recurse )
- {
- dfd = opendir(dname);
- if( dfd == 0 && errno == EACCES && flg_force )
- {
- old_mode = (cur_file_stat.st_mode & 07777);
- if( chmod(dname, (0700|old_mode)) )
- return error(errno, "", dname);
-
- dfd = opendir(dname);
- }
- if( dfd == 0 ) return error(errno, "", dname);
-
- while((ent=readdir(dfd)))
- {
- if( strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 )
- continue;
-
- alloca(0); /* Free up if using fake version */
- execute(dname, ent->d_name);
- }
- closedir(dfd);
- if( old_mode != -1 )
- chmod(dname, old_mode);
- }
-
- if( cmd_tok&DO_ADIR )
- {
- lstat(dname, &cur_file_stat);
- exec_for_item(1, dname);
- }
- return 0;
-}
-
-void exec_for_item(when, fname)
-int when; char * fname;
-{
- int rv = -1;
- switch(cmd_tok)
- {
- case CMD_FT: rv = cmd_ft(fname); break;
-
- case CMD_CAT: rv = copy_file(fname, "-"); break;
-
- case CMD_CHGRP: /* And fall */
- case CMD_CHMOD: /* And fall */
- case CMD_CHOWN: rv = copy_modes(fname); break;
-
- case CMD_CP: rv = cmd_cp(fname); break;
- case CMD_MV: rv = cmd_mv(fname); break;
- case CMD_RM: rv = cmd_rm(fname); break;
-
- case CMD_EXTAR: error(EINVAL, "", "No code."); exit(1);
-
- case CMD_LN+OK_DIR+OK_NO_SOURCE:
- case CMD_LN: rv = cmd_ln(fname); break;
-
- case CMD_INSTALL: error(EINVAL, "", ""); exit(1);
-
- case CMD_MKDIR: rv = cmd_mkdir(fname); break;
- case CMD_MKFIFO: rv = cmd_mkfifo(fname); break;
-#ifdef S_IFSOCK
- case CMD_MKSOCK: rv = cmd_mksock(fname); break;
-#endif
- case CMD_MKNOD: break;
- }
-}
-
-void parse_perms(prefix, ustring)
-char * prefix; char * ustring;
-{
- char * userstr;
- char * groupstr;
- char * modestr;
- char * cp;
- struct passwd * pwd = 0;
- struct group * grp;
-
- userstr = alloca(strlen(prefix) + strlen(ustring) + 2);
- strcpy(userstr, prefix);
- strcat(userstr, ustring);
-
- /* Select User */
- cp = strchr(userstr, ':');
- if(!cp) cp = strchr(userstr, '.');
- if(cp) *cp = '\0';
-
- /* If there's a user */
- if( *userstr != 0 )
- {
- pwd = getpwnam(userstr);
- if(pwd == NULL)
- {
- if(!strisdigit(userstr) )
- {
- error(EINVAL, "Unknown user ", userstr);
- exit(1);
- }
- set_user = atoi(userstr);
- }
- else set_user = pwd->pw_uid;
- endpwent();
- }
- if(cp)
- {
- groupstr = cp+1;
- cp = strchr(groupstr, ':');
- if(!cp) cp = strchr(groupstr, '.');
- if(cp) *cp = '\0';
- if( *groupstr != '\0' )
- {
- grp = getgrnam(groupstr);
- if(grp == NULL)
- {
- if(!strisdigit(groupstr) )
- {
- error(EINVAL, "Unknown group ", groupstr);
- exit(1);
- }
- set_group = atoi(groupstr);
- }
- else set_group = grp->gr_gid;
- endgrent();
- }
- else if( pwd )
- set_group = pwd->pw_gid;
- }
- if(cp)
- {
- modestr = cp+1;
- if(strisdigit(modestr))
- set_mode = strtol(modestr, NULL, 8);
- else
- {
- strncpy(mode_str, modestr, sizeof(mode_str)-1);
- /* This is the time that the mode change will fail on syn error */
- (void) edit_mode(u_mask, mode_str);
- }
- }
-
- if( set_user < 0 && set_group < 0 && set_mode < 0 && *mode_str == 0)
- {
- error(EINVAL, "", "Permission string has no changes");
- exit(1);
- }
-}
-
-int edit_mode(mode, mode_str)
-int mode; char * mode_str;
-{
- char * str=mode_str;
-static mtab[] = {0, 0111, 0222, 0333, 0444, 0555, 0666, 0777 };
-
- int done_change = 0;
- int isdir = S_ISDIR(mode);
- int change_op = 0;
- int change_mask = u_mask;
- int v=0, s=0, nm=0;
-
- for(; *mode_str; mode_str++)
- {
- switch(*mode_str)
- {
- case ',': change_op = 0;
- change_mask=u_mask; continue;
- case '=': change_op = 1; if(0) {
- case '+': change_op = 2; } if(0) {
- case '-': change_op = 3; }
- v=0; nm=0;
- if(strchr(",=+-", mode_str[1]) == 0 ) continue;
- break;
- case 'a': if(change_op) goto ch_error;
- nm |= 07777; if(0) {
- case 'u': nm |= 04700; s= 6; } if(0) {
- case 'g': nm |= 02070; s= 3; } if(0) {
- case 'o': nm |= 01007; s= 0; }
- if(change_op==0) { change_mask=nm; continue; }
- v |= mtab[(mode>>s)&7];
- break;
- case 'r': v |= 0444; break;
- case 'w': v |= 0222; break;
- case 'x': v |= 0111; break;
- case 's': v |=06000; break;
- case 't': v |=01000; break;
- case 'X': v |= mtab[isdir]; break;
- default: goto ch_error;
- }
- switch(change_op)
- {
- case 0: goto ch_error;
- case 1: mode= ((mode&(~change_mask)) | (v&change_mask));
- break;
- case 2: mode= ( mode | (v&change_mask));
- break;
- case 3: mode= ( mode & ~(v&change_mask));
- break;
- }
- done_change=1;
- }
- if(!done_change)
- {
-ch_error:
- error(EINVAL, "Invalid mode string ", str);
- exit(1);
- }
- return mode;
-}
-
-int
-cmd_ft(fname)
-char * fname;
-{
-static char oldpath[2048] = "~";
-static int last_uid=-1, last_gid=-1, last_mode=-1;
- struct passwd * pptr;
- struct group * gptr;
-
- if( flg_verbose>1 )
- {
- char *p = 0;
- if( fname[1] ) p = strrchr(fname, '/');
- if( p )
- {
- *p = '\0';
- if( strcmp(fname, oldpath) != 0 )
- {
- strcpy(oldpath, fname);
- printf("%s/\n", oldpath);
- }
- *p = '/';
- }
- else if( *oldpath )
- *oldpath = '\0';
- if(p) printf("%s", p+1);
- else printf("%s", fname);
-
-#ifdef S_IFLNK
- if( S_ISLNK(cur_file_stat.st_mode))
- {
- char linkbuf[1024];
- int v;
- *linkbuf='\0';
- v = readlink(fname, linkbuf, sizeof(linkbuf));
- if(v>0) linkbuf[v] = '\0';
- printf("\t+%s", linkbuf);
- }
- else
-#endif
- if( cur_file_stat.st_mode != last_mode
- || cur_file_stat.st_uid != last_uid
- || cur_file_stat.st_gid != last_gid)
- {
- printf("\t");
- if( cur_file_stat.st_uid != last_uid )
- {
- pptr = getpwuid(cur_file_stat.st_uid);
- if( pptr )
- printf("%s", pptr->pw_name);
- else
- printf("%d", cur_file_stat.st_uid);
- }
- printf(":");
- if( cur_file_stat.st_gid != last_gid )
- {
- gptr = getgrgid(cur_file_stat.st_gid);
- if( gptr )
- printf("%s", gptr->gr_name);
- else
- printf("%d", cur_file_stat.st_gid);
- }
- if( (cur_file_stat.st_mode&07777) != (last_mode&07777) )
- printf(":%03o", cur_file_stat.st_mode & 07777);
-
- switch(cur_file_stat.st_mode & S_IFMT)
- {
- case S_IFDIR: printf("\td"); break;
- case S_IFIFO: printf("\tp"); break;
-#ifdef S_IFSOCK
- case S_IFSOCK: printf("\ts"); break;
-#endif
- case S_IFBLK: printf("\tb,%d,%d", cur_file_stat.st_rdev>>8,
- cur_file_stat.st_rdev&0xFF);
- break;
- case S_IFCHR: printf("\tc,%d,%d", cur_file_stat.st_rdev>>8,
- cur_file_stat.st_rdev&0xFF);
- break;
- }
- last_mode = ((cur_file_stat.st_mode&07777)|S_IFREG);
- if( (cur_file_stat.st_mode&07000) ) last_mode = -1;
- last_uid = cur_file_stat.st_uid;
- last_gid = cur_file_stat.st_gid;
- }
- printf("\n");
- }
- else printf("%s\n", fname);
-
- return 0;
-}
-
-int
-cmd_mkfifo(fname)
-char * fname;
-{
- int rv;
- int mode=0666;
- if( set_mode >= 0 ) mode=set_mode;
- rv = mknod(fname, S_IFIFO|mode, 0);
- if(rv<0)
- warning(errno, "Cannot create fifo ", fname);
- return rv;
-}
-
-#ifdef S_IFSOCK
-int
-cmd_mksock(fname)
-char * fname;
-{
- int rv, fd, len;
- struct sockaddr *adr;
-
- len = strlen(fname)+1 + sizeof(*adr) - sizeof(adr->sa_data);
- if( len < sizeof(*adr) ) len = sizeof(*adr);
-
- adr = alloca(len+2);
- adr->sa_family = AF_UNIX;
- strcpy(adr->sa_data, fname);
-
- rv = fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if( fd>=0 ) rv = bind(fd, adr, len);
- if( fd>=0 ) close(fd);
- if(set_mode >= 0 && chmod(fname, set_mode&07777) < 0 )
- warning(errno, "Chmod ", fname);
-
- if(rv<0)
- warning(errno, "Cannot create socket ", fname);
- return rv;
-}
-#endif
-
-int
-cmd_rm(fname)
-char * fname;
-{
- struct stat dirstat;
- int rv;
- char * buf, * p;
-
- if( S_ISDIR(cur_file_stat.st_mode) )
- if( !flg_recurse ) return error(EISDIR, "", fname);
-
- if( S_ISDIR(cur_file_stat.st_mode) )
- {
- if( rmdir(fname) >= 0 ) return 0;
- }
- else
- {
- if( unlink(fname) >= 0 ) return 0;
- }
-
- if( !flg_force )
- return error(errno, "", fname);
-
- /* Try VERY hard */
- buf = alloca(strlen(fname)+4);
- strcpy(buf, fname);
- p = strrchr(buf, '/');
- if( p ) strcpy(p+1, "."); else strcpy(buf, ".");
-
- if( stat(buf, &dirstat) < 0 ) return -1;
- if( chmod(buf, dirstat.st_mode|0700) < 0 ) return -1;
-
- if( S_ISDIR(cur_file_stat.st_mode) )
- rv = rmdir(fname);
- else
- rv = unlink(fname);
-
- chmod(buf, dirstat.st_mode);
-
- return rv;
-}
-
-void
-build_dest(dest, name, newpath)
-char * dest; char * name; char * newpath;
-{
- char * p;
- strcpy(dest, newpath);
- if( add_base )
- {
- strcat(dest, "/");
- p = strrchr(or_name, '/');
- if(p==0) strcat(dest, or_name);
- else strcat(dest, p+1);
- }
- if(strlen(name) <= or_offset) return;
- strcat(dest, name+or_offset);
-}
-
-int
-strisdigit(str)
-char * str;
-{
- if( str==0 || *str == 0 ) return 0;
-
- for(;*str; str++)
- if(*str>'9'|| *str<'0') return 0;
- return 1;
-}
-
-int
-cmd_mv(fname)
-char * fname;
-{
- char * destfile;
- destfile = alloca(strlen(fname)+strlen(cmd_string)+4);
-
- build_dest(destfile, fname, cmd_string);
-
- if( !flg_force && lstat(destfile, &access_stat) == 0 )
- return error(EEXIST, "", destfile);
-
- if( rename(fname, destfile) == 0 ) return 0;
-
- if( errno != EXDEV )
- return error(errno, "", fname);
-
- if( S_ISDIR(cur_file_stat.st_mode) )
- return error(EISDIR, "Can't rename across devices ", fname);
-
- if( copy_file(fname, destfile) != 0 ) return -1;
- copy_modes(destfile);
- return unlink(fname);
-}
-
-int
-cmd_ln(fname)
-char * fname;
-{
- char * destfile;
- destfile = alloca(strlen(fname)+strlen(cmd_string)+4);
-
- build_dest(destfile, fname, cmd_string);
-
- if( lstat(destfile, &access_stat) != -1 )
- {
- if( !flg_force ) return error(EEXIST, "", destfile);
- cmd_rm(destfile);
- }
-
-#ifdef S_IFLNK
- if( flg_symlink )
- {
- if( symlink(fname, destfile) == 0 ) return 0;
- }
- else
- {
-#endif
- if( link(fname, destfile) == 0 ) return 0;
-#ifdef S_IFLNK
- }
-#endif
-
- return error(errno, "", destfile);
-}
-
-int
-cmd_cp(fname)
-char * fname;
-{
- struct stat dest_stat;
- char * destfile;
- int no_dest = 0;
-
- destfile = alloca(strlen(fname)+strlen(cmd_string)+4);
-
- build_dest(destfile, fname, cmd_string);
-
- if( stat(destfile, &dest_stat) >= 0 )
- {
- if( dest_stat.st_ino == cur_file_stat.st_ino
- && dest_stat.st_dev == cur_file_stat.st_dev )
- {
- warning(EPERM, "Can't copy file to itself ", fname);
- return -1;
- }
- }
- else no_dest = 1;
-
- if( S_ISDIR(cur_file_stat.st_mode) )
- {
- if( !no_dest )
- {
- if( S_ISDIR(dest_stat.st_mode) ) return 0;
- if( unlink(destfile) < 0 )
- return error(errno, "Can't delete ", destfile);
- }
- return cmd_mkdir(destfile);
- }
- else if( S_ISDIR(dest_stat.st_mode) )
- return error(EPERM, "Can't copy non-directory to directory ", destfile);
- else if( S_ISREG(cur_file_stat.st_mode) )
- {
- /* Copy_ok - do we want to force a real file */;
- if( flg_force && !no_dest && !S_ISREG(dest_stat.st_mode) )
- cmd_rm(destfile);
- }
- else if( flg_recurse ) /* Don't copy other things while recursing */
- {
- return error(EPERM, "Can't copy ", fname);
- }
-
- if( copy_file(fname, destfile) != 0 ) return -1;
- if( flg_preserve ) copy_modes(destfile);
- return 0;
-}
-
-int
-copy_modes(file)
-char * file;
-{
- int user, group, mode;
- /* chown turns off set[ug]id bits for non-root,
- so do the chmod last. */
-
- /* Try to copy the old file's modtime and access time. */
- if(set_time)
- {
- struct utimbuf tv;
-
- tv.actime = cur_file_stat.st_atime;
- tv.modtime = cur_file_stat.st_mtime;
- if( set_time != -1 )
- tv.modtime = set_time;
- if (utime (file, &tv) && !flg_force)
- return error (errno, "", file);
- }
-
- /* Try to preserve ownership. For non-root it might fail, but that's ok.
- But root probably wants to know, e.g. if NFS disallows it. */
- user = cur_file_stat.st_uid; if(set_user>=0) user = set_user;
- group = cur_file_stat.st_gid; if(set_group>=0) group = set_group;
-
- if (chown (file, user, group)
- && (errno != EPERM || geteuid() == 0 || (flg_preserve==0 && flg_force==0)))
- error (errno, "Can't change perms for ", file);
-
- mode = cur_file_stat.st_mode;
- if(set_mode>=0) mode=set_mode;
- else if(*mode_str)
- mode = edit_mode(mode, mode_str);
-
- if (chmod (file, mode & 07777))
- return error (errno, "", file);
-
- return 0;
-}
-
-/* This copies from something to a file or stdout */
-/* If the source has zero blocks (possibly holes) the destination
- * is built with holes (assuming it's a normal file) */
-
-int
-copy_file(source, dest)
-char * source; char * dest;
-{
- char * buf;
- int sfd, dfd;
- struct stat st;
- int blksz = BUFSIZ;
- int cc;
- char * ptr;
- int hole_flag = 0;
- int retv = 0;
- int no_seek;
- int mmode = 0666;
-
- if(flg_verbose>1) printf("%s -> %s\n", source, dest);
- if( strcmp(source, "-") == 0 )
- sfd = 0;
- else
- {
- sfd = open(source, O_RDONLY);
- if(sfd<0) return error(errno, "", source);
- mmode = (cur_file_stat.st_mode&0777);
- }
-
- if( strcmp(dest, "-") == 0 )
- dfd = 1;
- else
- {
- dfd = open(dest, O_WRONLY|O_TRUNC|O_CREAT, mmode);
- if(dfd<0)
- {
- close(sfd);
- return error(errno, "Cannot create ", source);
- }
- }
-
- if( fstat(dfd, &st) )
- {
- retv = error(errno, "", dest);
- no_seek = 1;
- }
- else
- {
-#ifndef __BCC__
- blksz = st.st_blksize;
-#endif
- no_seek = !S_ISREG(st.st_mode);
- }
- buf = alloca(blksz + sizeof(int));
- if( buf == 0 ) return error(0, "Out of memory", "");
-
- for(;;)
- {
- cc = read(sfd, buf, blksz);
- if(cc<0)
- {
- retv = error(errno, "", source);
- goto exit_now;
- }
- if(cc==0) break;
- buf[cc] = 1;
- for(ptr=buf; *ptr==0 ; ptr++) ;
- if((hole_flag = (ptr == buf+cc)))
- { /* Make a hole */
- if( lseek(dfd, (off_t) cc, SEEK_CUR) < 0 )
- {
- retv = error(errno, "", dest);
- goto exit_now;
- }
- }
- else
- {
- if( cc != write(dfd, buf, cc))
- {
- retv = error(errno, "", dest);
- goto exit_now;
- }
- }
- }
- if( hole_flag )
- {
- if( lseek(dfd, (off_t) -1, SEEK_CUR) < 0
- || write(dfd, "", 1) != 1 )
- {
- retv = error(errno, "", dest);
- goto exit_now;
- }
- }
-
-exit_now:
- if(sfd>2) close(sfd);
- if(dfd>2) close(dfd);
- return retv;
-}
-
-void
-Usage()
-{
- int i;
-
- printf("FileTool Usage: %s%s", prog_name[0]=='-'?"ft -":"", prog_name);
- if( cmd_tok == CMD_FT )
- {
- printf(" --[com_name] [-options] [files]\n");
- printf("\nAvailable commands are:\n");
- }
-
- for(i=1; command_list[i].name; i++)
- {
- if( cmd_tok == CMD_FT )
- printf(" %s --%s", prog_name, command_list[i].name);
- else if( cmd_tok != command_list[i].cmd )
- continue;
-
- if( *command_list[i].opts )
- printf(" [-%s]", command_list[i].opts);
- switch(command_list[i].argpat)
- {
- case 1: printf(" <info> [files]"); break;
- case -1: printf(" [files] [dest]"); break;
- case 0: printf(" [files]"); break;
- default: printf(" path [bcu] major minor"); break;
- }
- printf("\n");
- }
-
- exit(99);
-}
-
-int
-cmd_mkdir(dirname)
-char * dirname;
-{
- int retv;
- int mode = 0777;
- if( set_mode >= 0 ) mode = set_mode;
-
- retv = mkdir(dirname, mode);
- if(retv<0)
- {
- if(flg_mkpdir && errno == ENOENT)
- {
- /* Create parents */
- }
- }
- if( retv>=0 && cmd_tok == CMD_MKDIR )
- {
- if( set_user > 0 || set_group > 0 )
- {
- if( chown(dirname, set_user, set_group) < 0)
- warning(errno, "Cannot change directory owner ", dirname);
- else if( chmod (dirname, mode & 07777) )
- warning(errno, "", dirname);
- }
- }
-
- if(retv<0) error(errno, "Cannot create directory ", dirname);
- return retv;
-}
-
-int
-cmd_mknod()
-{
- int device;
- int rv = -1;
- int mode=0666;
- if( set_mode >= 0 ) mode=set_mode;
-
- device = (atoi(flist[2])<<8) + atoi(flist[3]);
-
- if(flist[1][0] == 'b')
- rv = mknod(flist[0], S_IFBLK|mode, device);
- else if(flist[1][0] == 'c' || flist[1][0] == 'u')
- rv = mknod(flist[0], S_IFCHR|mode, device);
- else Usage();
-
- if(rv<0)
- {
- error(errno, "", flist[0]);
- exit(1);
- }
- return rv;
-}
-
-int
-warning(enumber, estr, eobj)
-int enumber; char * estr; char * eobj;
-{
- if(flg_verbose)
- return error(enumber, estr, eobj);
- return 0;
-}
-
-int
-error(enumber, estr, eobj)
-int enumber; char * estr; char * eobj;
-{
- fprintf(stderr, "%s%s: ", prog_name[0]=='-'?"ft":"", prog_name);
- fprintf(stderr, "%s%s: %s\n", estr, eobj, strerror(enumber));
- return -1;
-}