[hackers] [sbase] implement cp and mv and improve rm || William Haddon

From: <hg_AT_suckless.org>
Date: Mon, 30 Jan 2012 23:41:45 +0100 (CET)

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