[hackers] [sbase] implement cp and mv and improve rm || William Haddon
changeset: 100:84bab9f95caf
tag: tip
user: William Haddon <william_AT_haddonthethird.net>
date: Mon Jan 30 22:41:33 2012 +0000
files: LICENSE Makefile TODO config.mk cp.1 cp.c fs.h mv.1 mv.c rm.1 rm.c util.h util/cp.c util/enmasse.c util/fnck.c util/rm.c
description:
implement cp and mv and improve rm
diff -r cf054f63a5c5 -r 84bab9f95caf LICENSE
--- a/LICENSE Thu Jan 19 00:04:04 2012 +0000
+++ b/LICENSE Mon Jan 30 22:41:33 2012 +0000
_AT_@ -7,6 +7,7 @@
© 2011 Hiltjo Posthuma <hiltjo_AT_codemadness.org>
© 2011 pancake <pancake_AT_youterm.com>
© 2011 Random832 <random832_AT_fastmail.us>
+© 2012 William Haddon <william_AT_haddonthethird.net>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff -r cf054f63a5c5 -r 84bab9f95caf Makefile
--- a/Makefile Thu Jan 19 00:04:04 2012 +0000
+++ b/Makefile Mon Jan 30 22:41:33 2012 +0000
_AT_@ -1,17 +1,20 @@
include config.mk
-HDR = text.h util.h
+HDR = fs.h text.h util.h
LIB = \
util/afgets.o \
util/agetcwd.o \
util/apathmax.o \
util/concat.o \
+ util/cp.o \
util/enmasse.o \
util/eprintf.o \
util/enprintf.o \
util/estrtol.o \
+ util/fnck.o \
util/putword.o \
util/recurse.o \
+ util/rm.o \
util/venprintf.o
SRC = \
_AT_@ -21,6 +24,7 @@
chown.c \
cksum.c \
cmp.c \
+ cp.c \
date.c \
dirname.c \
echo.c \
_AT_@ -33,6 +37,7 @@
ls.c \
mkdir.c \
mkfifo.c \
+ mv.c \
nl.c \
nohup.c \
pwd.c \
_AT_@ -56,7 +61,8 @@
$(OBJ): util.h config.mk
$(BIN): util.a
-cat.o grep.o tail.o: text.h
+cat.o cp.o mv.o grep.o tail.o: text.h
+cp.o mv.o rm.o: fs.h
.o:
_AT_echo LD $@
diff -r cf054f63a5c5 -r 84bab9f95caf TODO
--- a/TODO Thu Jan 19 00:04:04 2012 +0000
+++ b/TODO Mon Jan 30 22:41:33 2012 +0000
_AT_@ -1,17 +1,11 @@
comm [-123] file1 file2
-cp [-r] file [name]
-cp [-r] [file...] [directory]
-
cut [-bcfs] [-d delim] list [file...]
diff [-ru] file1 file2
id [-gnru] [user]
-mv file [name]
-mv [file...] directory
-
paste [-s] [-d list] [file...]
printf format [argument...]
diff -r cf054f63a5c5 -r 84bab9f95caf config.mk
--- a/config.mk Thu Jan 19 00:04:04 2012 +0000
+++ b/config.mk Mon Jan 30 22:41:33 2012 +0000
_AT_@ -10,7 +10,7 @@
LD = $(CC)
CPPFLAGS = -D_POSIX_C_SOURCE=200112L
CFLAGS = -Os -ansi -Wall -pedantic $(CPPFLAGS)
-LDFLAGS = -static #-s
+LDFLAGS =
#CC = tcc
#LD = $(CC)
diff -r cf054f63a5c5 -r 84bab9f95caf cp.1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cp.1 Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,22 @@
+.TH CP 1 sbase\-VERSION
+.SH NAME
+cp \- copy files and directories
+.SH SYNOPSIS
+.B cp
+.RB [ \-r ]
+.I file
+.RI [ name ]
+.P
+.B cp
+.RB [ \-r ]
+.RI [ file ...]
+.RI [ directory ]
+.SH DESCRIPTION
+.B cp
+copies a given file, naming it the given name. If multiple files are listed
+they will be copied into the given directory.
+.SH OPTIONS
+.TP
+.B \-r
+copies directories recursively. If this flag is not specified, directories are
+not copied.
diff -r cf054f63a5c5 -r 84bab9f95caf cp.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cp.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "fs.h"
+#include "util.h"
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ char c;
+
+ while((c = getopt(argc, argv, "r")) != -1)
+ switch(c) {
+ case 'r':
+ cp_rflag = true;
+ break;
+ default:
+ exit(EXIT_FAILURE);
+ }
+ if(argc > 3 && !cp_rflag && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode)))
+ eprintf("%s: not a directory\n", argv[argc-1]);
+ enmasse(argc - optind, &argv[optind], cp);
+ return EXIT_SUCCESS;
+}
diff -r cf054f63a5c5 -r 84bab9f95caf fs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fs.h Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdbool.h>
+
+extern bool cp_rflag;
+extern bool rm_fflag;
+extern bool rm_rflag;
+
+int cp(const char *, const char *);
+void rm(const char *);
diff -r cf054f63a5c5 -r 84bab9f95caf mv.1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mv.1 Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,16 @@
+.TH MV 1 sbase\-VERSION
+.SH NAME
+mv \- move files and directories
+.SH SYNOPSIS
+.B mv
+.I file
+.RI [ name ]
+.P
+.B mv
+.RI [ file ...]
+.RI [ directory ]
+.SH DESCRIPTION
+.B mv
+moves or renames a given file or directory, naming it the given name. If
+multiple files and directories are listed they will be moved into the given
+directory.
diff -r cf054f63a5c5 -r 84bab9f95caf mv.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mv.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,39 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "fs.h"
+#include "util.h"
+
+int mv(const char *, const char *);
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+
+ if(getopt(argc, argv, "") != -1)
+ exit(EXIT_FAILURE);
+ if(argc > 3 && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode)))
+ eprintf("%s: not a directory\n", argv[argc-1]);
+ enmasse(argc - optind, &argv[optind], mv);
+ return EXIT_SUCCESS;
+}
+
+int
+mv (const char *s1, const char *s2)
+{
+ if (rename(s1, s2) == 0)
+ return 0;
+ if (errno == EXDEV)
+ {
+ cp_rflag = true;
+ rm_rflag = true;
+ cp(s1, s2);
+ rm(s1);
+ return 0;
+ }
+ return -1;
+}
diff -r cf054f63a5c5 -r 84bab9f95caf rm.1
--- a/rm.1 Thu Jan 19 00:04:04 2012 +0000
+++ b/rm.1 Mon Jan 30 22:41:33 2012 +0000
_AT_@ -14,6 +14,7 @@
ignore files that cannot be removed.
.TP
.B \-r
-remove directories recursively.
+remove directories recursively. If this flag is not specified, directories are
+not removed.
.SH SEE ALSO
.IR remove (3)
diff -r cf054f63a5c5 -r 84bab9f95caf rm.c
--- a/rm.c Thu Jan 19 00:04:04 2012 +0000
+++ b/rm.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -3,39 +3,33 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/stat.h>
+#include "fs.h"
#include "util.h"
-static void rm(const char *);
-
-static bool fflag = false;
-static bool rflag = false;
-
int
main(int argc, char *argv[])
{
char c;
+ struct stat st;
while((c = getopt(argc, argv, "fr")) != -1)
switch(c) {
case 'f':
- fflag = true;
+ rm_fflag = true;
break;
case 'r':
- rflag = true;
+ rm_rflag = true;
break;
default:
exit(EXIT_FAILURE);
}
- for(; optind < argc; optind++)
- rm(argv[optind]);
+ for(; optind < argc; optind++) {
+ if(!rm_rflag && stat(argv[optind], &st) == 0 &&
+ S_ISDIR(st.st_mode))
+ fprintf(stderr, "%s: is a directory\n", argv[optind]);
+ else
+ rm(argv[optind]);
+ }
return EXIT_SUCCESS;
}
-
-void
-rm(const char *path)
-{
- if(rflag)
- recurse(path, rm);
- if(remove(path) == -1 && !fflag)
- eprintf("remove %s:", path);
-}
diff -r cf054f63a5c5 -r 84bab9f95caf util.h
--- a/util.h Thu Jan 19 00:04:04 2012 +0000
+++ b/util.h Mon Jan 30 22:41:33 2012 +0000
_AT_@ -8,5 +8,6 @@
void eprintf(const char *, ...);
void enprintf(int, const char *, ...);
long estrtol(const char *, int);
+void fnck(const char *, const char *, int (*)(const char *, const char *));
void putword(const char *);
void recurse(const char *, void (*)(const char *));
diff -r cf054f63a5c5 -r 84bab9f95caf util/cp.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/cp.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,59 @@
+/* See LICENSE file for copyright and license details. */
+#include <dirent.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "../fs.h"
+#include "../text.h"
+#include "../util.h"
+
+bool cp_rflag = false;
+
+int
+cp(const char *s1, const char *s2)
+{
+ FILE *f1, *f2;
+ char *ns1, *ns2;
+ long size1, size2;
+ struct dirent *d;
+ struct stat st;
+ DIR *dp;
+
+ if (stat(s1, &st) == 0 && S_ISDIR(st.st_mode)) {
+ if (!cp_rflag) {
+ eprintf("%s: is a directory\n", s1);
+ }
+ else {
+ if(!(dp = opendir(s1)))
+ eprintf("opendir %s:", s1);
+ if (mkdir(s2, st.st_mode) == -1 && errno != EEXIST)
+ eprintf("mkdir %s:", s2);
+ apathmax(&ns1, &size1);
+ apathmax(&ns2, &size2);
+ while((d = readdir(dp)))
+ if(strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
+ if(snprintf(ns1, size1, "%s/%s", s1, d->d_name) > size1)
+ eprintf("%s/%s: filename too long\n", s1, d->d_name);
+ if(snprintf(ns2, size2, "%s/%s", s2, d->d_name) > size2)
+ eprintf("%s/%s: filename too long\n", s2, d->d_name);
+ fnck(ns1, ns2, cp);
+ }
+ closedir(dp);
+ free(ns1);
+ free(ns2);
+ }
+ return 0;
+ }
+ if(!(f1 = fopen(s1, "r")))
+ eprintf("fopen %s:", s1);
+ if(!(f2 = fopen(s2, "w")))
+ eprintf("fopen %s:", s2);
+ concat(f1, s1, f2, s2);
+ fclose(f2);
+ fclose(f1);
+ return 0;
+}
diff -r cf054f63a5c5 -r 84bab9f95caf util/enmasse.c
--- a/util/enmasse.c Thu Jan 19 00:04:04 2012 +0000
+++ b/util/enmasse.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -7,8 +7,6 @@
#include <sys/stat.h>
#include "../util.h"
-static void fnck(const char *, const char *, int (*)(const char *, const char *));
-
void
enmasse(int argc, char **argv, int (*fn)(const char *, const char *))
{
_AT_@ -32,15 +30,3 @@
}
free(buf);
}
-
-void
-fnck(const char *a, const char *b, int (*fn)(const char *, const char *))
-{
- struct stat sta, stb;
-
- if(stat(a, &sta) == 0 && stat(b, &stb) == 0
- && sta.st_dev == stb.st_dev && sta.st_ino == stb.st_ino)
- eprintf("%s -> %s: same file\n", a, b);
- if(fn(a, b) == -1)
- eprintf("%s -> %s:", a, b);
-}
diff -r cf054f63a5c5 -r 84bab9f95caf util/fnck.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/fnck.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,15 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+#include "../util.h"
+
+void
+fnck(const char *a, const char *b, int (*fn)(const char *, const char *))
+{
+ struct stat sta, stb;
+
+ if(stat(a, &sta) == 0 && stat(b, &stb) == 0
+ && sta.st_dev == stb.st_dev && sta.st_ino == stb.st_ino)
+ eprintf("%s -> %s: same file\n", a, b);
+ if(fn(a, b) == -1)
+ eprintf("%s -> %s:", a, b);
+}
diff -r cf054f63a5c5 -r 84bab9f95caf util/rm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/rm.c Mon Jan 30 22:41:33 2012 +0000
_AT_@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdbool.h>
+#include <stdio.h>
+#include "../fs.h"
+#include "../util.h"
+
+bool rm_fflag = false;
+bool rm_rflag = false;
+
+void
+rm(const char *path)
+{
+ if(rm_rflag)
+ recurse(path, rm);
+ if(remove(path) == -1 && !rm_fflag)
+ eprintf("remove %s:", path);
+}
Received on Mon Jan 30 2012 - 23:41:45 CET
This archive was generated by hypermail 2.3.0
: Mon Jan 30 2012 - 23:48:07 CET