aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/sam
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-09-30 17:47:42 +0000
committerrsc <devnull@localhost>2003-09-30 17:47:42 +0000
commited7c8e8d02c02bdbff1e88a6d8d1419f39af48ad (patch)
treeebcd32d20b0df2584bce713fefa87620ecd1cce7 /src/cmd/sam
parentb2cfc4e2e71d0f0a5113ddfbd93c8285cc4d74e4 (diff)
downloadplan9port-ed7c8e8d02c02bdbff1e88a6d8d1419f39af48ad.tar.gz
plan9port-ed7c8e8d02c02bdbff1e88a6d8d1419f39af48ad.tar.bz2
plan9port-ed7c8e8d02c02bdbff1e88a6d8d1419f39af48ad.zip
Initial import.
Diffstat (limited to 'src/cmd/sam')
-rw-r--r--src/cmd/sam/README29
-rw-r--r--src/cmd/sam/_libc.h40
-rw-r--r--src/cmd/sam/err39
-rw-r--r--src/cmd/sam/plumb.h17
-rw-r--r--src/cmd/sam/string.c193
-rw-r--r--src/cmd/sam/sys.c60
-rw-r--r--src/cmd/sam/util.c54
7 files changed, 432 insertions, 0 deletions
diff --git a/src/cmd/sam/README b/src/cmd/sam/README
new file mode 100644
index 00000000..b78a89da
--- /dev/null
+++ b/src/cmd/sam/README
@@ -0,0 +1,29 @@
+This is sam (not including samterm) from the 4th edition of Plan 9,
+with changes so that it can be compiled under unix.
+(Tested on Solaris 7 and Debian 3.0r1.)
+
+Some extra libraries are needed. First, fetch libutf-2.0 and libfmt-2.0
+from
+ http://pdos.lcs.mit.edu/~rsc/software/
+
+(Beware that in libfmt/fmt.c there is a line that says:
+ 'u', __ifmt, /* in Plan 9, __flagfmt */
+Thus, sam will have to fmtinstall the other thing. Other ported programs
+may have to do the same. The fmt library should probably print messages
+about bad format characters to stderr, since no one seems to check the
+return codes.)
+
+Compile and install those two libraries.
+Set PREFIX in the Makefile to match, then compile sam.
+
+Your C compiler will emit many complaints of the form:
+ sam.c:496: warning: passing arg 1 of `bufread' from incompatible pointer type
+
+This is because the Plan 9 compiler has a slightly different (better,
+ala Oberon) type system than ISO C. Popular compilers generate the right
+code, so in an act of civil disobediance I changed just enough to get
+it to compile, but left the type errors in. Now the next C standard can
+adopt this extension, because at least one important C program uses it!
+
+-- Scott Schwartz, 4 July 2003
+
diff --git a/src/cmd/sam/_libc.h b/src/cmd/sam/_libc.h
new file mode 100644
index 00000000..65618918
--- /dev/null
+++ b/src/cmd/sam/_libc.h
@@ -0,0 +1,40 @@
+#define __USE_UNIX98 // for pread/pwrite, supposedly
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "utf.h"
+#include "fmt.h"
+
+#define nil 0
+#define dup dup2
+#define exec execv
+#define seek lseek
+#define getwd getcwd
+#define USED(a)
+#define SET(a)
+
+enum {
+ OREAD = 0,
+ OWRITE = 1,
+ ORDWR = 2,
+ OCEXEC = 4,
+ ORCLOSE = 8
+};
+
+enum {
+ ERRMAX = 255
+};
+
+void exits(const char *);
+void _exits(const char *);
+int notify (void(*f)(void *, char *));
+int create(char *, int, int);
+int errstr(char *, int);
diff --git a/src/cmd/sam/err b/src/cmd/sam/err
new file mode 100644
index 00000000..2a36c23b
--- /dev/null
+++ b/src/cmd/sam/err
@@ -0,0 +1,39 @@
+address.c: In function `filematch':
+address.c:159: warning: passing arg 1 of `bufreset' from incompatible pointer type
+address.c:160: warning: passing arg 1 of `bufinsert' from incompatible pointer type
+file.c: In function `mergeextend':
+file.c:117: warning: passing arg 1 of `bufread' from incompatible pointer type
+file.c: In function `fileinsert':
+file.c:275: warning: passing arg 1 of `bufinsert' from incompatible pointer type
+file.c: In function `filedelete':
+file.c:301: warning: passing arg 1 of `bufdelete' from incompatible pointer type
+file.c: In function `fileundelete':
+file.c:324: warning: passing arg 1 of `bufread' from incompatible pointer type
+file.c: In function `filereadc':
+file.c:339: warning: passing arg 1 of `bufread' from incompatible pointer type
+file.c: In function `fileload':
+file.c:405: warning: passing arg 1 of `bufload' from incompatible pointer type
+file.c: In function `fileundo':
+file.c:528: warning: passing arg 1 of `bufdelete' from incompatible pointer type
+file.c:546: warning: passing arg 1 of `bufinsert' from incompatible pointer type
+file.c: In function `fileclose':
+file.c:604: warning: passing arg 1 of `bufclose' from incompatible pointer type
+io.c: In function `readio':
+io.c:90: warning: passing arg 1 of `bufload' from incompatible pointer type
+io.c: In function `writeio':
+io.c:152: warning: passing arg 1 of `bufread' from incompatible pointer type
+mesg.c: In function `inmesg':
+mesg.c:248: warning: passing arg 1 of `bufread' from incompatible pointer type
+mesg.c: In function `snarf':
+mesg.c:568: warning: passing arg 1 of `bufread' from incompatible pointer type
+mesg.c: In function `setgenstr':
+mesg.c:612: warning: passing arg 1 of `bufread' from incompatible pointer type
+sam.c: In function `readcmd':
+sam.c:496: warning: passing arg 1 of `bufread' from incompatible pointer type
+sam.c: In function `copy':
+sam.c:676: warning: passing arg 1 of `bufread' from incompatible pointer type
+xec.c: In function `s_cmd':
+xec.c:234: warning: passing arg 1 of `bufread' from incompatible pointer type
+xec.c:243: warning: passing arg 1 of `bufread' from incompatible pointer type
+xec.c: In function `display':
+xec.c:401: warning: passing arg 1 of `bufread' from incompatible pointer type
diff --git a/src/cmd/sam/plumb.h b/src/cmd/sam/plumb.h
new file mode 100644
index 00000000..d376acd0
--- /dev/null
+++ b/src/cmd/sam/plumb.h
@@ -0,0 +1,17 @@
+typedef struct Plumbmsg Plumbmsg;
+
+struct Plumbmsg {
+ char *src;
+ char *dst;
+ char *wdir;
+ char *type;
+ char *attr;
+ char *data;
+ int ndata;
+};
+
+char *plumbunpackattr(char*);
+char *plumbpack(Plumbmsg *, int *);
+int plumbfree(Plumbmsg *);
+char *cleanname(char*);
+
diff --git a/src/cmd/sam/string.c b/src/cmd/sam/string.c
new file mode 100644
index 00000000..9a4b9a71
--- /dev/null
+++ b/src/cmd/sam/string.c
@@ -0,0 +1,193 @@
+#include "sam.h"
+
+#define MINSIZE 16 /* minimum number of chars allocated */
+#define MAXSIZE 256 /* maximum number of chars for an empty string */
+
+
+void
+Strinit(String *p)
+{
+ p->s = emalloc(MINSIZE*RUNESIZE);
+ p->n = 0;
+ p->size = MINSIZE;
+}
+
+void
+Strinit0(String *p)
+{
+ p->s = emalloc(MINSIZE*RUNESIZE);
+ p->s[0] = 0;
+ p->n = 1;
+ p->size = MINSIZE;
+}
+
+void
+Strclose(String *p)
+{
+ free(p->s);
+}
+
+void
+Strzero(String *p)
+{
+ if(p->size > MAXSIZE){
+ p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */
+ p->size = MAXSIZE;
+ }
+ p->n = 0;
+}
+
+int
+Strlen(Rune *r)
+{
+ Rune *s;
+
+ for(s=r; *s; s++)
+ ;
+ return s-r;
+}
+
+void
+Strdupl(String *p, Rune *s) /* copies the null */
+{
+ p->n = Strlen(s)+1;
+ Strinsure(p, p->n);
+ memmove(p->s, s, p->n*RUNESIZE);
+}
+
+void
+Strduplstr(String *p, String *q) /* will copy the null if there's one there */
+{
+ Strinsure(p, q->n);
+ p->n = q->n;
+ memmove(p->s, q->s, q->n*RUNESIZE);
+}
+
+void
+Straddc(String *p, int c)
+{
+ Strinsure(p, p->n+1);
+ p->s[p->n++] = c;
+}
+
+void
+Strinsure(String *p, ulong n)
+{
+ if(n > STRSIZE)
+ error(Etoolong);
+ if(p->size < n){ /* p needs to grow */
+ n += 100;
+ p->s = erealloc(p->s, n*RUNESIZE);
+ p->size = n;
+ }
+}
+
+void
+Strinsert(String *p, String *q, Posn p0)
+{
+ Strinsure(p, p->n+q->n);
+ memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE);
+ memmove(p->s+p0, q->s, q->n*RUNESIZE);
+ p->n += q->n;
+}
+
+void
+Strdelete(String *p, Posn p1, Posn p2)
+{
+ memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE);
+ p->n -= p2-p1;
+}
+
+int
+Strcmp(String *a, String *b)
+{
+ int i, c;
+
+ for(i=0; i<a->n && i<b->n; i++)
+ if(c = (a->s[i] - b->s[i])) /* assign = */
+ return c;
+ /* damn NULs confuse everything */
+ i = a->n - b->n;
+ if(i == 1){
+ if(a->s[a->n-1] == 0)
+ return 0;
+ }else if(i == -1){
+ if(b->s[b->n-1] == 0)
+ return 0;
+ }
+ return i;
+}
+
+int
+Strispre(String *a, String *b)
+{
+ int i;
+
+ for(i=0; i<a->n && i<b->n; i++){
+ if(a->s[i] - b->s[i]){ /* assign = */
+ if(a->s[i] == 0)
+ return 1;
+ return 0;
+ }
+ }
+ return i == a->n;
+}
+
+char*
+Strtoc(String *s)
+{
+ int i;
+ char *c, *d;
+ Rune *r;
+ c = emalloc(s->n*UTFmax + 1); /* worst case UTFmax bytes per rune, plus NUL */
+ d = c;
+ r = s->s;
+ for(i=0; i<s->n; i++)
+ d += runetochar(d, r++);
+ if(d==c || d[-1]!=0)
+ *d = 0;
+ return c;
+
+}
+
+/*
+ * Build very temporary String from Rune*
+ */
+String*
+tmprstr(Rune *r, int n)
+{
+ static String p;
+
+ p.s = r;
+ p.n = n;
+ p.size = n;
+ return &p;
+}
+
+/*
+ * Convert null-terminated char* into String
+ */
+String*
+tmpcstr(char *s)
+{
+ String *p;
+ Rune *r;
+ int i, n;
+
+ n = utflen(s); /* don't include NUL */
+ p = emalloc(sizeof(String));
+ r = emalloc(n*RUNESIZE);
+ p->s = r;
+ for(i=0; i<n; i++,r++)
+ s += chartorune(r, s);
+ p->n = n;
+ p->size = n;
+ return p;
+}
+
+void
+freetmpstr(String *s)
+{
+ free(s->s);
+ free(s);
+}
diff --git a/src/cmd/sam/sys.c b/src/cmd/sam/sys.c
new file mode 100644
index 00000000..db54d28d
--- /dev/null
+++ b/src/cmd/sam/sys.c
@@ -0,0 +1,60 @@
+#include "sam.h"
+
+static int inerror=FALSE;
+
+/*
+ * A reasonable interface to the system calls
+ */
+
+void
+resetsys(void)
+{
+ inerror = FALSE;
+}
+
+void
+syserror(char *a)
+{
+ char buf[ERRMAX];
+
+ if(!inerror){
+ inerror=TRUE;
+ errstr(buf, sizeof buf);
+ dprint("%s: ", a);
+ error_s(Eio, buf);
+ }
+}
+
+int
+Read(int f, void *a, int n)
+{
+ char buf[ERRMAX];
+
+ if(read(f, (char *)a, n)!=n) {
+ if (lastfile)
+ lastfile->rescuing = 1;
+ errstr(buf, sizeof buf);
+ if (downloaded)
+ fprint(2, "read error: %s\n", buf);
+ rescue();
+ exits("read");
+ }
+ return n;
+}
+
+int
+Write(int f, void *a, int n)
+{
+ int m;
+
+ if((m=write(f, (char *)a, n))!=n)
+ syserror("write");
+ return m;
+}
+
+void
+Seek(int f, long n, int w)
+{
+ if(seek(f, n, w)==-1)
+ syserror("seek");
+}
diff --git a/src/cmd/sam/util.c b/src/cmd/sam/util.c
new file mode 100644
index 00000000..b2599689
--- /dev/null
+++ b/src/cmd/sam/util.c
@@ -0,0 +1,54 @@
+#include "sam.h"
+
+void
+cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
+{
+ uchar *q;
+ Rune *s;
+ int j, w;
+
+ /*
+ * Always guaranteed that n bytes may be interpreted
+ * without worrying about partial runes. This may mean
+ * reading up to UTFmax-1 more bytes than n; the caller
+ * knows this. If n is a firm limit, the caller should
+ * set p[n] = 0.
+ */
+ q = (uchar*)p;
+ s = r;
+ for(j=0; j<n; j+=w){
+ if(*q < Runeself){
+ w = 1;
+ *s = *q++;
+ }else{
+ w = chartorune(s, (char*)q);
+ q += w;
+ }
+ if(*s)
+ s++;
+ else if(nulls)
+ *nulls = TRUE;
+ }
+ *nb = (char*)q-p;
+ *nr = s-r;
+}
+
+void*
+fbufalloc(void)
+{
+ return emalloc(BUFSIZE);
+}
+
+void
+fbuffree(void *f)
+{
+ free(f);
+}
+
+uint
+min(uint a, uint b)
+{
+ if(a < b)
+ return a;
+ return b;
+}