applied sl's patch, thanks Stanley! - 9base - revived minimalist port of Plan 9… | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 443de6b2ff7295c63811275a5e97659a11a5d5c0 | |
parent 6d2a7da4aae588f1bb970dbe40d66a8585d4c0bb | |
Author: Anselm R Garbe <[email protected]> | |
Date: Sun, 8 May 2011 08:26:38 +0000 | |
applied sl's patch, thanks Stanley! | |
Diffstat: | |
M Makefile | 2 ++ | |
A rm/Makefile | 10 ++++++++++ | |
A rm/rm.1 | 28 ++++++++++++++++++++++++++++ | |
A rm/rm.c | 112 +++++++++++++++++++++++++++++… | |
A ssam/Makefile | 21 +++++++++++++++++++++ | |
A ssam/ssam | 41 +++++++++++++++++++++++++++++… | |
A ssam/ssam.1 | 72 +++++++++++++++++++++++++++++… | |
M std.mk | 2 +- | |
8 files changed, 287 insertions(+), 1 deletion(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -38,6 +38,7 @@ SUBDIRS = lib9\ | |
primes\ | |
rc\ | |
read\ | |
+ rm\ | |
sam\ | |
sha1sum\ | |
sed\ | |
@@ -45,6 +46,7 @@ SUBDIRS = lib9\ | |
sleep\ | |
sort\ | |
split\ | |
+ ssam\ | |
strings\ | |
tail\ | |
tee\ | |
diff --git a/rm/Makefile b/rm/Makefile | |
@@ -0,0 +1,10 @@ | |
+# rm - rm unix port from plan9 | |
+# Depends on ../lib9 | |
+ | |
+TARG = rm | |
+ | |
+include ../std.mk | |
+ | |
+pre-uninstall: | |
+ | |
+post-install: | |
diff --git a/rm/rm.1 b/rm/rm.1 | |
@@ -0,0 +1,28 @@ | |
+.TH RM 1 | |
+.SH NAME | |
+rm \- remove files | |
+.SH SYNOPSIS | |
+.B rm | |
+[ | |
+.B -fr | |
+] | |
+.I file ... | |
+.SH DESCRIPTION | |
+.I Rm | |
+removes files or directories. | |
+A directory is removed only if it is empty. | |
+Removal of a file requires write permission in its directory, | |
+but neither read nor write permission on the file itself. | |
+The options are | |
+.TP | |
+.B -f | |
+Don't report files that can't be removed. | |
+.TP | |
+.B -r | |
+Recursively delete the | |
+entire contents of a directory | |
+and the directory itself. | |
+.SH SOURCE | |
+.B \*9/src/cmd/rm.c | |
+.SH "SEE ALSO" | |
+.IR remove (3) | |
diff --git a/rm/rm.c b/rm/rm.c | |
@@ -0,0 +1,112 @@ | |
+#include <u.h> | |
+#include <sys/stat.h> | |
+#include <libc.h> | |
+ | |
+#define rmdir p9rmdir | |
+ | |
+char errbuf[ERRMAX]; | |
+int ignerr = 0; | |
+ | |
+static void | |
+err(char *f) | |
+{ | |
+ if(!ignerr){ | |
+ errbuf[0] = '\0'; | |
+ errstr(errbuf, sizeof errbuf); | |
+ fprint(2, "rm: %s: %s\n", f, errbuf); | |
+ } | |
+} | |
+ | |
+int | |
+issymlink(char *name) | |
+{ | |
+ struct stat s; | |
+ return lstat(name, &s) >= 0 && S_ISLNK(s.st_mode); | |
+} | |
+ | |
+/* | |
+ * f is a non-empty directory. Remove its contents and then it. | |
+ */ | |
+void | |
+rmdir(char *f) | |
+{ | |
+ char *name; | |
+ int fd, i, j, n, ndir, nname; | |
+ Dir *dirbuf; | |
+ | |
+ fd = open(f, OREAD); | |
+ if(fd < 0){ | |
+ err(f); | |
+ return; | |
+ } | |
+ n = dirreadall(fd, &dirbuf); | |
+ close(fd); | |
+ if(n < 0){ | |
+ err("dirreadall"); | |
+ return; | |
+ } | |
+ | |
+ nname = strlen(f)+1+STATMAX+1; /* plenty! */ | |
+ name = malloc(nname); | |
+ if(name == 0){ | |
+ err("memory allocation"); | |
+ return; | |
+ } | |
+ | |
+ ndir = 0; | |
+ for(i=0; i<n; i++){ | |
+ snprint(name, nname, "%s/%s", f, dirbuf[i].name); | |
+ if(remove(name) != -1 || issymlink(name)) | |
+ dirbuf[i].qid.type = QTFILE; /* so we won't rec… | |
+ else{ | |
+ if(dirbuf[i].qid.type & QTDIR) | |
+ ndir++; | |
+ else | |
+ err(name); | |
+ } | |
+ } | |
+ if(ndir) | |
+ for(j=0; j<n; j++) | |
+ if(dirbuf[j].qid.type & QTDIR){ | |
+ snprint(name, nname, "%s/%s", f, dirbuf[j].nam… | |
+ rmdir(name); | |
+ } | |
+ if(remove(f) == -1) | |
+ err(f); | |
+ free(name); | |
+ free(dirbuf); | |
+} | |
+void | |
+main(int argc, char *argv[]) | |
+{ | |
+ int i; | |
+ int recurse; | |
+ char *f; | |
+ Dir *db; | |
+ | |
+ ignerr = 0; | |
+ recurse = 0; | |
+ ARGBEGIN{ | |
+ case 'r': | |
+ recurse = 1; | |
+ break; | |
+ case 'f': | |
+ ignerr = 1; | |
+ break; | |
+ default: | |
+ fprint(2, "usage: rm [-fr] file ...\n"); | |
+ exits("usage"); | |
+ }ARGEND | |
+ for(i=0; i<argc; i++){ | |
+ f = argv[i]; | |
+ if(remove(f) != -1) | |
+ continue; | |
+ db = nil; | |
+ if(recurse && (db=dirstat(f))!=nil && (db->qid.type&QTDIR)) | |
+ rmdir(f); | |
+ else | |
+ err(f); | |
+ free(db); | |
+ } | |
+ exits(errbuf); | |
+} | |
diff --git a/ssam/Makefile b/ssam/Makefile | |
@@ -0,0 +1,21 @@ | |
+# ssam - stream interface for sam | |
+# Depends on ../lib9 | |
+ | |
+include ../config.mk | |
+ | |
+all: | |
+ @echo built ssam | |
+ | |
+install: | |
+ @cp -f ssam ${DESTDIR}${PREFIX}/bin/ | |
+ @chmod 755 ${DESTDIR}${PREFIX}/bin/ssam | |
+ @cp -f ssam.1 ${DESTDIR}${MANPREFIX}/man1/ | |
+ @chmod 444 ${DESTDIR}${MANPREFIX}/man1/ssam.1 | |
+ | |
+uninstall: | |
+ @rm -f ${DESTDIR}${PREFIX}/bin/ssam | |
+ @rm -f ${DESTDIR}${MANPREFIX}/man1/ssam.1 | |
+ | |
+clean: | |
+ @true | |
+ | |
diff --git a/ssam/ssam b/ssam/ssam | |
@@ -0,0 +1,41 @@ | |
+#!/usr/local/plan9/bin/rc | |
+# ssam - stream interface to sam | |
+ | |
+flagfmt='n,e script,f sfile' | |
+args='[ file ... ]' | |
+if(! ifs=() eval `{getflags $*}){ | |
+ usage | |
+ exit usage | |
+} | |
+ | |
+if(~ $#flage 0 && ~ $#flagf 0) { | |
+ if(~ $#* 0) { | |
+ usage | |
+ exit usage | |
+ } | |
+ flage=$1 | |
+ shift | |
+} | |
+ | |
+if(~ $#TMPDIR 0) | |
+ TMPDIR=/tmp | |
+tmp=$TMPDIR/ssam.tmp.$USER.$pid | |
+cat $* >$tmp | |
+ | |
+{ | |
+ # select entire file | |
+ echo ',{' | |
+ echo k | |
+ echo '}' | |
+ echo 0k | |
+ | |
+ # run scripts, print | |
+ if(! ~ $#flagf 0) | |
+ cat $flagf | |
+ if(! ~ $#flage 0) | |
+ echo $flage | |
+ if(~ $#flagn 0) | |
+ echo , | |
+} | sam -d $tmp >[2]/dev/null | |
+ | |
+rm -f $tmp | |
diff --git a/ssam/ssam.1 b/ssam/ssam.1 | |
@@ -0,0 +1,72 @@ | |
+.TH SSAM 1 | |
+.SH NAME | |
+ssam \- stream interface to sam | |
+.SH SYNOPSIS | |
+.B ssam | |
+[ | |
+.B -n | |
+] | |
+[ | |
+.B -e | |
+.I script | |
+] | |
+[ | |
+.B -f | |
+.I sfile | |
+] | |
+[ | |
+.I file ... | |
+] | |
+.SH DESCRIPTION | |
+.I Ssam | |
+copies the named | |
+.I files | |
+(standard input default) to the standard output, edited by a script of | |
+.IR sam | |
+commands (q.v.). | |
+When the script starts, the entire input is selected. | |
+The | |
+.B -f | |
+option causes the script to be taken from file | |
+.IR sfile . | |
+If there is a | |
+.B -e | |
+option and no | |
+.BR -f , | |
+the flag | |
+.B -e | |
+may be omitted. | |
+The | |
+.B -n | |
+option suppresses the default output. | |
+.ne 4 | |
+.SH EXAMPLES | |
+.TP | |
+.B ssam -n ,10p file | |
+Print first 10 lines of file. | |
+.TP | |
+.B ssam 'y/[a-zA-Z]+/ c/\en/' *.ms | |
+Print one word per line. | |
+.TP | |
+.B ssam 's/\en\en+/\en/g' | |
+Delete empty lines from standard input. | |
+.TP | |
+.B ssam 's/UNIX/& system/g' | |
+Replace every instance of | |
+.L UNIX | |
+by | |
+.LR "UNIX system" . | |
+.TP | |
+.B ssam 'y/[a-zA-Z]+/ c/\en/' | grep . | sort | uniq -c | |
+Count frequency of words read from standard input. | |
+.SH SOURCE | |
+.B \*9/bin/ssam | |
+.SH SEE ALSO | |
+.IR sed (1), | |
+.IR sam (1), | |
+.IR regexp (7) | |
+.PP | |
+Rob Pike, | |
+``The text editor sam''. | |
+.SH BUGS | |
+Ssam consumes all of standard input before running the script. | |
diff --git a/std.mk b/std.mk | |
@@ -6,7 +6,7 @@ MANFILE ?= ${TARG}.1 | |
include ../config.mk | |
all: ${TARG} | |
- @strip ${TARG} | |
+# @strip ${TARG} | |
@echo built ${TARG} | |
install: install-default post-install |