Browse Source

Plan 9 from Bell Labs 2005-01-08

David du Colombier 16 years ago
parent
commit
bf6e93acfb

+ 10 - 10
dist/replica/_plan9.db

@@ -116,7 +116,7 @@
 386/bin/aux/mnihongo - 775 sys sys 1104121979 138518
 386/bin/aux/mouse - 775 sys sys 1104121979 44026
 386/bin/aux/ms2 - 775 sys sys 1104121980 81824
-386/bin/aux/msexceltables - 775 sys sys 1105019969 80904
+386/bin/aux/msexceltables - 775 sys sys 1105070896 80904
 386/bin/aux/mswordstrings - 775 sys sys 1104121980 65317
 386/bin/aux/na - 775 sys sys 1104121980 154635
 386/bin/aux/nfsmount - 775 sys sys 1104121981 234092
@@ -5369,7 +5369,7 @@ sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1071245466 14094
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
 sys/src/9/pc/ether8139.c - 664 sys sys 1086987324 18362
-sys/src/9/pc/ether8169.c - 664 sys sys 1103641602 22531
+sys/src/9/pc/ether8169.c - 664 sys sys 1105109291 22498
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1055689887 32296
 sys/src/9/pc/ether82557.c - 664 sys sys 1098848151 30040
 sys/src/9/pc/ether83815.c - 664 sys sys 1081706477 23479
@@ -5433,7 +5433,7 @@ sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
 sys/src/9/pc/sdata.c - 664 sys sys 1099487462 50970
 sys/src/9/pc/sdmylex.c - 664 sys sys 1071245460 27812
 sys/src/9/pc/sdscsi.c - 664 sys sys 1077033661 7487
-sys/src/9/pc/trap.c - 664 sys sys 1105030146 20520
+sys/src/9/pc/trap.c - 664 sys sys 1105109602 20537
 sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
 sys/src/9/pc/uartpci.c - 664 sys sys 1096379063 2891
 sys/src/9/pc/usb.h - 664 sys sys 1099760881 3650
@@ -7059,7 +7059,7 @@ sys/src/cmd/aux/lines.c - 664 sys sys 1015008782 546
 sys/src/cmd/aux/lis - 775 sys sys 944960794 45
 sys/src/cmd/aux/listen.c - 664 sys sys 1093452954 8142
 sys/src/cmd/aux/listen1.c - 664 sys sys 1093452955 2018
-sys/src/cmd/aux/mkfile - 664 sys sys 1084415958 946
+sys/src/cmd/aux/mkfile - 664 sys sys 1105123164 962
 sys/src/cmd/aux/mklatinkbd.c - 664 sys sys 953253425 3813
 sys/src/cmd/aux/mnihongo - 20000000775 sys sys 944960789 0
 sys/src/cmd/aux/mnihongo/README - 664 sys sys 944960789 475
@@ -7068,6 +7068,7 @@ sys/src/cmd/aux/mnihongo/mnihongo.c - 664 sys sys 946759402 6406
 sys/src/cmd/aux/mnihongo/tmac.nihongo - 664 sys sys 944960789 22
 sys/src/cmd/aux/mouse.c - 664 sys sys 1063855425 7049
 sys/src/cmd/aux/ms2.c - 664 sys sys 1015008685 3129
+sys/src/cmd/aux/msexceltables.c - 664 sys sys 1105123098 13134
 sys/src/cmd/aux/mswordstrings.c - 664 sys sys 952201344 5767
 sys/src/cmd/aux/na - 20000000775 sys sys 955036627 0
 sys/src/cmd/aux/na/mkfile - 664 sys sys 955036627 121
@@ -10918,11 +10919,11 @@ sys/src/cmd/upas/send/tryit - 664 sys sys 944961322 584
 sys/src/cmd/upas/smtp - 20000000775 sys sys 988250017 0
 sys/src/cmd/upas/smtp/greylist.c - 664 sys sys 1091126808 6470
 sys/src/cmd/upas/smtp/mkfile - 664 sys sys 1067722781 746
-sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1098803923 5150
+sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1105114609 6024
 sys/src/cmd/upas/smtp/rfc822.y - 664 sys sys 1064589606 13417
 sys/src/cmd/upas/smtp/rmtdns.c - 664 sys sys 1015013150 1069
-sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1097901337 19565
-sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1064589597 1084
+sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1105114610 20113
+sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1105114610 1111
 sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1102093207 30350
 sys/src/cmd/upas/smtp/smtpd.h - 664 sys sys 1067722781 1111
 sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1061836986 6949
@@ -12431,7 +12432,7 @@ sys/src/libventi/strdup.c - 664 sys sys 1045502096 203
 sys/src/libventi/venti.txt - 664 sys sys 1045502097 4347
 sys/src/libventi/zero.c - 664 sys sys 1045502097 1509
 sys/src/mkfile - 664 sys sys 1073061130 1006
-sys/src/mkfile.proto - 664 sys sys 1104430482 266
+sys/src/mkfile.proto - 664 sys sys 1105121349 265
 tmp - 20000000555 sys sys 953999902 0
 usr - 20000000775 sys sys 953406542 0
 usr/glenda - 20000000775 glenda glenda 953406571 0
@@ -12448,8 +12449,7 @@ usr/glenda/lib/acme.dump.small - 664 glenda glenda 1019273919 828
 usr/glenda/lib/first.window - 775 glenda glenda 1018974192 65
 usr/glenda/lib/newstime - 664 glenda glenda 953406587 0
 usr/glenda/lib/plumbing - 664 glenda glenda 953406587 89
-usr/glenda/lib/profile - 664 glenda glenda 1021580005 847
+usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
-386/bin/aux/msexceltables - 775 sys sys 1105070896 80904

+ 9 - 8
dist/replica/plan9.db

@@ -5369,7 +5369,7 @@ sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1071245466 14094
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
 sys/src/9/pc/ether8139.c - 664 sys sys 1086987324 18362
-sys/src/9/pc/ether8169.c - 664 sys sys 1103641602 22531
+sys/src/9/pc/ether8169.c - 664 sys sys 1105109291 22498
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1055689887 32296
 sys/src/9/pc/ether82557.c - 664 sys sys 1098848151 30040
 sys/src/9/pc/ether83815.c - 664 sys sys 1081706477 23479
@@ -5433,7 +5433,7 @@ sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
 sys/src/9/pc/sdata.c - 664 sys sys 1099487462 50970
 sys/src/9/pc/sdmylex.c - 664 sys sys 1071245460 27812
 sys/src/9/pc/sdscsi.c - 664 sys sys 1077033661 7487
-sys/src/9/pc/trap.c - 664 sys sys 1105030146 20520
+sys/src/9/pc/trap.c - 664 sys sys 1105109602 20537
 sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
 sys/src/9/pc/uartpci.c - 664 sys sys 1096379063 2891
 sys/src/9/pc/usb.h - 664 sys sys 1099760881 3650
@@ -7059,7 +7059,7 @@ sys/src/cmd/aux/lines.c - 664 sys sys 1015008782 546
 sys/src/cmd/aux/lis - 775 sys sys 944960794 45
 sys/src/cmd/aux/listen.c - 664 sys sys 1093452954 8142
 sys/src/cmd/aux/listen1.c - 664 sys sys 1093452955 2018
-sys/src/cmd/aux/mkfile - 664 sys sys 1084415958 946
+sys/src/cmd/aux/mkfile - 664 sys sys 1105123164 962
 sys/src/cmd/aux/mklatinkbd.c - 664 sys sys 953253425 3813
 sys/src/cmd/aux/mnihongo - 20000000775 sys sys 944960789 0
 sys/src/cmd/aux/mnihongo/README - 664 sys sys 944960789 475
@@ -7068,6 +7068,7 @@ sys/src/cmd/aux/mnihongo/mnihongo.c - 664 sys sys 946759402 6406
 sys/src/cmd/aux/mnihongo/tmac.nihongo - 664 sys sys 944960789 22
 sys/src/cmd/aux/mouse.c - 664 sys sys 1063855425 7049
 sys/src/cmd/aux/ms2.c - 664 sys sys 1015008685 3129
+sys/src/cmd/aux/msexceltables.c - 664 sys sys 1105123098 13134
 sys/src/cmd/aux/mswordstrings.c - 664 sys sys 952201344 5767
 sys/src/cmd/aux/na - 20000000775 sys sys 955036627 0
 sys/src/cmd/aux/na/mkfile - 664 sys sys 955036627 121
@@ -10918,11 +10919,11 @@ sys/src/cmd/upas/send/tryit - 664 sys sys 944961322 584
 sys/src/cmd/upas/smtp - 20000000775 sys sys 988250017 0
 sys/src/cmd/upas/smtp/greylist.c - 664 sys sys 1091126808 6470
 sys/src/cmd/upas/smtp/mkfile - 664 sys sys 1067722781 746
-sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1098803923 5150
+sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1105114609 6024
 sys/src/cmd/upas/smtp/rfc822.y - 664 sys sys 1064589606 13417
 sys/src/cmd/upas/smtp/rmtdns.c - 664 sys sys 1015013150 1069
-sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1097901337 19565
-sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1064589597 1084
+sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1105114610 20113
+sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1105114610 1111
 sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1102093207 30350
 sys/src/cmd/upas/smtp/smtpd.h - 664 sys sys 1067722781 1111
 sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1061836986 6949
@@ -12431,7 +12432,7 @@ sys/src/libventi/strdup.c - 664 sys sys 1045502096 203
 sys/src/libventi/venti.txt - 664 sys sys 1045502097 4347
 sys/src/libventi/zero.c - 664 sys sys 1045502097 1509
 sys/src/mkfile - 664 sys sys 1073061130 1006
-sys/src/mkfile.proto - 664 sys sys 1104430482 266
+sys/src/mkfile.proto - 664 sys sys 1105121349 265
 tmp - 20000000555 sys sys 953999902 0
 usr - 20000000775 sys sys 953406542 0
 usr/glenda - 20000000775 glenda glenda 953406571 0
@@ -12448,7 +12449,7 @@ usr/glenda/lib/acme.dump.small - 664 glenda glenda 1019273919 828
 usr/glenda/lib/first.window - 775 glenda glenda 1018974192 65
 usr/glenda/lib/newstime - 664 glenda glenda 953406587 0
 usr/glenda/lib/plumbing - 664 glenda glenda 953406587 89
-usr/glenda/lib/profile - 664 glenda glenda 1021580005 847
+usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0

+ 9 - 0
dist/replica/plan9.log

@@ -18293,3 +18293,12 @@
 1105030959 3 c sys/src/9/pc/trap.c - 664 sys sys 1105030146 20520
 1105030959 4 c sys/src/9/ppc/trap.c - 664 sys sys 1105030152 18384
 1105072367 0 c 386/bin/aux/msexceltables - 775 sys sys 1105070896 80904
+1105110175 0 c sys/src/9/pc/trap.c - 664 sys sys 1105109602 20537
+1105110175 1 c sys/src/9/pc/ether8169.c - 664 sys sys 1105109291 22498
+1105115577 0 c sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1105114609 6024
+1105115577 1 c sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1105114610 20113
+1105115577 2 c sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1105114610 1111
+1105122778 0 c sys/src/mkfile.proto - 664 sys sys 1105121349 265
+1105124578 0 c sys/src/cmd/aux/mkfile - 664 sys sys 1105123164 962
+1105124578 1 a sys/src/cmd/aux/msexceltables.c - 664 sys sys 1105123098 13134
+1105129979 0 c usr/glenda/lib/profile - 664 glenda glenda 1105128663 890

+ 0 - 1
sys/src/9/pc/ether8169.c

@@ -784,7 +784,6 @@ rtl8169receive(Ether* edev)
 			case Pid0:
 				if(control & Tcpf){
 					ctlr->tcpf++;
-					print("T%8.8uX+", control);
 					break;
 				}
 				bp->flag |= Btcpck;

+ 2 - 0
sys/src/9/pc/trap.c

@@ -313,6 +313,8 @@ trap(Ureg* ureg)
 		cycles(&up->kentry);
 	}
 
+	clockintr = 0;
+
 	vno = ureg->trap;
 	if(ctl = vctl[vno]){
 		if(ctl->isintr){

+ 1 - 0
sys/src/cmd/aux/mkfile

@@ -17,6 +17,7 @@ TARG=\
 	listen1\
 	mklatinkbd\
 	ms2\
+	msexceltables\
 	mswordstrings\
 	mouse\
 	nfsmount\

+ 725 - 0
sys/src/cmd/aux/msexceltables.c

@@ -0,0 +1,725 @@
+/* msexceltables.c    Steve Simon    5-Jan-2005 */
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+
+enum {
+	Tillegal = 0,
+	Tnumber,		// cell types
+	Tlabel,
+	Tindex,
+	Tbool,
+	Terror,
+
+	Ver8 = 0x600,		// only BIFF8 and BIFF8x files support unicode
+};
+	
+	
+typedef struct Biff Biff;
+typedef struct Col Col;
+typedef struct Row Row;
+
+struct Row {
+	Row *next;
+	int r;
+	Col *col;
+};
+
+struct Col {
+	Col *next;
+	int c;
+	int f;
+	int type;
+	union {
+		int index;
+		int error;
+		int bool;
+		char *label;
+		double number;
+	};
+};
+
+struct  Biff {
+	Biobuf *bp;
+	int op;
+	int len;
+};
+
+// options
+static int Nopad = 0;		// disable padding cells to colum width
+static int Trunc = 0;		// truncate cells to colum width
+static int All = 0;		// dump all sheet types, Worksheets only by default
+static char *Delim = " ";	// field delimiter
+static int Debug = 0;
+
+// file scope
+static int Defwidth = 10;	// default colum width if non given
+static int Biffver;		// file vesion
+static int Datemode;		// date ref: 1899-Dec-31 or 1904-jan-1
+static char **Strtab = nil;	// label contents heap
+static int Nstrtab = 0;		// # of above
+static int *Xf;			// array of extended format indices
+static int Nxf = 0;		// # of above
+static Biobuf *bo;		// stdout (sic)
+
+// table scope
+static int *Width = nil;	// array of colum widths
+static int Nwidths = 0;		// # of above
+static int Ncols = -1;		// max colums in table used
+static int Content = 0;		// type code for contents of sheet
+static Row *Root = nil;		// one worksheet's worth of cells
+				
+static char *Months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+static char *Errmsgs[] = {
+	[0x0]	"#NULL!",	// intersection of two cell ranges is empty
+	[0x7]	"#DIV/0!",	// division by zero	
+	[0xf]	"#VALUE!",	// wrong type of operand
+	[0x17]	"#REF!",	// illegal or deleted cell reference
+	[0x1d]	"#NAME?",	// wrong function or range name
+	[0x24]	"#NUM!",	// value range overflow
+	[0x2a]	"#N/A!",	// argument of function not available
+};
+
+	
+void
+cell(int r, int c, int f, int type, void *val)
+{
+	Row *row, *nrow;
+	Col *col, *ncol;
+
+	if (c > Ncols)
+		Ncols = c;
+
+	if ((ncol = malloc(sizeof(Col))) == nil)
+		sysfatal("no memory\n");
+	ncol->c = c;
+	ncol->f = f;
+	ncol->type = type;
+	ncol->next = nil;
+
+	switch(type){
+	case Tnumber:	ncol->number = *(double *)val;	break;
+	case Tlabel:	ncol->label = (char *)val;	break;
+	case Tindex:	ncol->index = *(int *)val;	break;
+	case Tbool:	ncol->bool = *(int *)val;	break;
+	case Terror:	ncol->error = *(int *)val;	break;
+	default:	sysfatal("can't happen error\n");
+	}
+
+	if (Root == nil || Root->r > r){
+		if ((nrow = malloc(sizeof(Row))) == nil)
+			sysfatal("no memory\n");
+		nrow->col = ncol;
+		ncol->next = nil;
+		nrow->r = r;
+		nrow->next = Root;
+		Root = nrow;
+		return;
+	}
+
+	for (row = Root; row; row = row->next){
+		if (row->r == r){
+			if (row->col->c > c){
+				ncol->next = row->col;
+				row->col = ncol;
+				return;
+			}
+			else{
+				for (col = row->col; col; col = col->next)
+					if (col->next == nil || col->next->c > c){
+						ncol->next = col->next;
+						col->next = ncol;
+						return;
+					}
+			}
+		}
+
+		if (row->next == nil || row->next->r > r){
+			if ((nrow = malloc(sizeof(Row))) == nil)
+				sysfatal("no memory\n");
+			nrow->col = ncol;
+			nrow->r = r;
+			nrow->next = row->next;
+			row->next = nrow;
+			return;
+		}
+	}
+	sysfatal("cannot happen error\n");
+}
+
+void
+numfmt(int fmt, int min, int max, double num)
+{
+	long t;
+	char buf[1024];
+	struct Tm *tm;
+
+	/* Beware - These epochs are wrong, this
+	 * is to remain compatible with Lotus-123
+	 * which believed 1900 was a leap year
+	 */
+	if (Datemode)
+		t = (num-24107)*60*60*24;	// epoch = 1/1/1904
+	else
+		t = (num-25569)*60*60*24;	// epoch = 31/12/1899
+	tm = localtime(t);
+
+	if (fmt == 9)
+		snprint(buf, sizeof(buf),"%.0f%%", num);
+	else
+	if (fmt == 10)
+		snprint(buf, sizeof(buf),"%f%%", num);
+	else
+	if (fmt == 11 || fmt == 48)
+		snprint(buf, sizeof(buf),"%e", num);
+	else
+	if (fmt >= 14 && fmt <= 17)
+		snprint(buf, sizeof(buf),"%d-%s-%d",
+			tm->mday, Months[tm->mon], tm->year+1900);
+	else
+	if ((fmt >= 18 && fmt <= 21) || (fmt >= 45 && fmt <= 47))
+		snprint(buf, sizeof(buf),"%02d:%02d:%02d", tm->hour, tm->min, tm->sec);
+	else
+	if (fmt == 22)
+		snprint(buf, sizeof(buf),"%02d:%02d:%02d %d-%s-%d",
+			tm->hour, tm->min, tm->sec,
+			tm->mday, Months[tm->mon], tm->year+1900);
+	else
+		snprint(buf, sizeof(buf),"%g", num);
+	Bprint(bo, "%-*.*q", min, max, buf);
+}
+
+void
+dump(void)
+{
+	Row *r;
+	Col *c;
+	int i, min, max;
+
+	for (r = Root; r; r = r->next){
+		for (c = r->col; c; c = c->next){
+			if (c->c < 0 || c->c >= Nwidths || (min = Width[c->c]) == 0)
+				min = Defwidth;
+			if ((c->next && c->c == c->next->c) || Nopad)
+				min = 0;
+			max = -1;
+			if (Trunc && min > 2)
+				max = min -2;		// FIXME: -2 because of bug %q format ?
+
+			switch(c->type){
+			case Tnumber:
+				if (Xf[c->f] == 0)
+					Bprint(bo, "%-*.*g", min, max, c->number);
+				else
+					numfmt(Xf[c->f], min, max, c->number);
+				break;
+			case Tlabel:
+				Bprint(bo, "%-*.*q", min, max, c->label);
+				break;
+			case Tbool:
+				Bprint(bo, "%-*.*s", min, max, (c->bool)? "True": "False");
+				break;
+			case Tindex:
+				if (c->error < 0 || c->error >= Nstrtab)
+					sysfatal("SST string out of range - corrupt file?\n");
+				Bprint(bo, "%-*.*q", min, max, Strtab[c->index]);
+				break;
+			case Terror:
+				if (c->error < 0 || c->error >= nelem(Errmsgs))
+					Bprint(bo, "#ERR=%d", c->index);
+				else
+					Bprint(bo, "%-*.*q", min, max, Errmsgs[c->error]);
+				break;
+			default:
+				sysfatal("cannot happen error\n");
+				break;
+			}
+
+			if (c->next){
+				if (c->next->c == c->c)		// bar charts
+					Bprint(bo, "=");
+				else{
+					Bprint(bo, "%s", Delim);
+					for (i = c->c; c->next && i < c->next->c -1; i++)
+						Bprint(bo, "%-*.*s%s", min, max, "", Delim);
+				}
+			}
+		}
+		if (r->next)
+			for (i = r->r; i < r->next->r; i++)
+				Bprint(bo, "\n");
+
+	}
+	Bprint(bo, "\n");
+}
+
+void
+release(void)
+{
+	Row *r, *or;
+	Col *c, *oc;
+
+	r = Root;
+	while(r){
+		c = r->col;
+		while(c){
+			if (c->type == Tlabel)
+				free(c->label);
+			oc = c;
+			c = c->next;
+			free(oc);
+		}
+		or = r;
+		r = r->next;
+		free(or);
+	}
+	Root = nil;
+
+	free(Width);
+	Width = nil;
+	Nwidths = 0;
+	Ncols = -1;
+}
+
+static int 
+getrec(Biff *b)
+{
+	int c;
+	if ((c = Bgetc(b->bp)) == -1)
+		return -1;		// real EOF
+	b->op = c;
+	if ((c = Bgetc(b->bp)) == -1)
+		sysfatal("unexpected EOF - %r\n");
+	b->op |= c << 8;
+	if ((c = Bgetc(b->bp)) == -1)
+		sysfatal("unexpected EOF - %r\n");
+	b->len = c;
+	if ((c = Bgetc(b->bp)) == -1)
+		sysfatal("unexpected EOF - %r\n");
+	b->len |= c << 8;
+	if (b->op == 0 && b->len == 0)
+		return -1;
+	return 0;
+}
+
+static uvlong
+gint(Biff *b, int n)
+{
+	int i, c;
+	uvlong vl, rc;
+
+	if (b->len < n)
+		return -1;
+	rc = 0;
+	for (i = 0; i < n; i++){
+		if ((c = Bgetc(b->bp)) == -1)
+			sysfatal("unexpected EOF - %r\n");
+		b->len--;
+		vl = c;
+		rc |= vl << (8*i);
+	}
+	return rc;
+}
+
+void
+skip(Biff *b, int len)
+{
+	if (Bseek(b->bp, len, 1) == -1)
+		sysfatal("seek failed - %r\n");
+	b->len -= len;
+}
+
+void
+gmem(Biff *b, void *p, int n)
+{
+	if (b->len < n)
+		sysfatal("short record %d < %d\n", b->len, n);
+	if (Bread(b->bp, p, n) != n)
+		sysfatal("unexpected EOF - %r\n");
+	b->len -= n;
+}
+
+double
+grk(Biff *b)
+{
+	int f;
+	uvlong n;
+	double d;
+
+	n = gint(b, 4);
+	f = n & 3;
+	n &= ~3LL;
+	if (f & 2){
+		d = n / 4.0;
+	}
+	else{
+		n <<= 32;
+		memcpy(&d, &n, sizeof(d));
+	}
+
+	if (f & 1)
+		d /= 100.0;
+	return d;
+}
+
+double
+gdoub(Biff *b)
+{
+	double d;
+	uvlong n = gint(b, 8);
+	memcpy(&d, &n, sizeof(n));
+	return d;
+}
+
+char *
+gstr(Biff *b, int len_width)
+{
+	Rune r;
+	int len, opt;
+	char *buf, *p;
+
+	if (b->len == 0){
+		if (getrec(b) == -1)
+			sysfatal("expected CONTINUE, got EOF\n");
+		if (b->op != 0x03c)	
+			sysfatal("expected CONTINUE, got op=0x%x\n", b->op);
+	}
+
+	switch(len_width){
+	case 16: len = gint(b, 2); break;
+	case 8:  len = gint(b, 1); break;
+	default: sysfatal("can't happen error\n"); SET(len); break;
+	}
+
+	if (Biffver != Ver8){
+		if ((buf = calloc(len+1, sizeof(char))) == nil)
+			sysfatal("no memory\n");
+		gmem(b, buf, len);
+		return buf;
+	}
+
+	if ((buf = calloc(len+1, sizeof(char)*UTFmax)) == nil)
+		sysfatal("no memory\n");
+	p = buf;
+
+	if (len == 0)
+		return buf;
+
+	opt = gint(b, 1);
+	if (opt & 0x0c)
+		sysfatal("Can't parse rich or Asian phonetic text - no documentation!\n");
+
+	while(len--){
+		r = gint(b, (opt & 1)? sizeof(Rune): sizeof(char));
+		p += runetochar(p, &r);
+	}
+	return buf;
+}
+
+void
+xd(Biff *b)
+{
+	uchar buf[16];
+	int addr, n, i, j;
+
+	addr = 0;
+	while (b->len){
+		n = (b->len >= sizeof(buf))? sizeof(buf): b->len;
+		gmem(b, buf, n);
+
+		Bprint(bo, "	%6d  ", addr);
+		addr += n;
+
+		for (i = 0; i < n; i++)
+			Bprint(bo, "%02x ", buf[i]);
+		for (j = i; j < 16; j++)
+			Bprint(bo, "   ");
+		Bprint(bo, "  ");
+		for (i = 0; i < n; i++)
+			Bprint(bo, "%c", isprint(buf[i])? buf[i]: '.');
+		Bprint(bo, "\n");
+	}
+}
+
+void
+sst(Biff *b)
+{
+	int n;
+	
+	skip(b, 4);			// total # strings
+	Nstrtab = gint(b, 4);		// # unique strings
+	if ((Strtab = calloc(Nstrtab, sizeof(char *))) == nil)
+		sysfatal("no memory\n");
+	for (n = 0; n < Nstrtab; n++)
+		Strtab[n] = gstr(b, 16);
+}
+
+void
+boolerr(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// col
+	int f = gint(b, 2);		// formatting ref
+	int v = gint(b, 1);		// bool value / err code
+	int t = gint(b, 1);		// type
+	cell(r, c, f, (t)? Terror: Tbool, &v);
+}
+
+void
+rk(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// col
+	int f = gint(b, 2);		// formatting ref
+	double v = grk(b);		// value
+	cell(r, c, f, Tnumber, &v);
+}
+
+void
+mulrk(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// first col
+	while (b->len >= 6){
+		int f = gint(b, 2);	// formatting ref
+		double v = grk(b);	// value
+		cell(r, c++, f, Tnumber, &v);
+	}
+}
+
+void
+number(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// col
+	int f = gint(b, 2);		// formatting ref
+	double v = gdoub(b);		// double 
+	cell(r, c, f, Tnumber, &v);
+}
+
+void
+label(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// col
+	int f = gint(b, 2);		// formatting ref
+	char *s = gstr(b, 16);		// byte string
+	cell(r, c, f, Tlabel, s);
+}
+
+
+void
+labelsst(Biff *b)
+{
+	int r = gint(b, 2);		// row
+	int c = gint(b, 2);		// col
+	int f = gint(b, 2);		// formatting ref
+	int i = gint(b, 2);		// sst string ref
+	cell(r, c, f, Tindex, &i);
+}
+
+void
+bof(Biff *b)
+{
+	Biffver = gint(b, 2);
+	Content = gint(b, 2);	
+}
+
+void
+defcolwidth(Biff *b)
+{
+	Defwidth = gint(b, 2);
+}
+
+void
+datemode(Biff *b)
+{
+	Datemode = gint(b, 2);
+}
+
+void
+eof(Biff *b)
+{
+	int i;
+	struct {
+		int n;
+		char *s;
+	} names[] = {
+		0x005,	"Workbook globals",
+		0x006,	"Visual Basic module",
+		0x010,	"Worksheet",
+		0x020,	"Chart",
+		0x040,	"Macro sheet",
+		0x100,	"Workspace file",
+	};
+		
+	if (Ncols != -1){
+		if (All){
+			for (i = 0; i < nelem(names); i++)
+				if (names[i].n == Content){
+					Bprint(bo, "\n# contents %s\n", names[i].s);
+					dump();
+				}
+		}
+		else 
+		if (Content == 0x10)
+			dump();
+	}
+	release();
+	USED(b);
+}
+
+void
+colinfo(Biff *b)
+{
+	int c;
+	int c1 = gint(b, 2);
+	int c2 = gint(b, 2);
+	int w  = gint(b, 2);
+
+	if (c2 >= Nwidths){
+		Nwidths = c2+20;
+		if ((Width = realloc(Width, Nwidths*sizeof(int))) == nil)
+			sysfatal("no memory\n");
+	}
+
+	w /= 256;
+
+	if (w > 100)
+		w = 100;
+	if (w < 0)
+		w = 0;
+
+	for (c = c1; c <= c2; c++)
+		Width[c] = w;
+}
+
+void
+xf(Biff *b)
+{
+	int fmt;
+	static int nalloc = 0;
+
+	skip(b, 2);
+	fmt = gint(b, 2);
+	if (nalloc >= Nxf){
+		nalloc += 20;
+		if ((Xf = realloc(Xf, nalloc*sizeof(int))) == nil)
+			sysfatal("no memory\n");
+	}
+	Xf[Nxf++] = fmt;
+}
+
+void
+writeaccess(Biff *b)
+{
+	Bprint(bo, "# author %s\n", gstr(b, 16));
+}
+
+void
+codepage(Biff *b)
+{
+	int codepage = gint(b, 2);
+	if (codepage != 1200)				// 1200 == UTF-16
+		Bprint(bo, "# codepage %d\n", codepage);
+}
+
+void
+xls2csv(Biobuf *bp)
+{
+	int i;
+	Biff biff, *b;
+	struct {
+		int op;
+		void (*func)(Biff *);
+	} dispatch[] = {
+		0x00a,	eof,
+		0x022,	datemode,
+		0x042,	codepage,
+		0x055,	defcolwidth,
+		0x05c,	writeaccess,
+		0x07d,	colinfo,
+		0x0bd,	mulrk,
+		0x0fc,	sst,
+		0x0fd,	labelsst,
+		0x203,	number,
+		0x204,	label,
+		0x205,	boolerr,
+		0x27e,	rk,
+		0x809,	bof,
+		0x0e0,	xf,
+	};		
+	
+	b = &biff;
+	b->bp = bp;
+	while(getrec(b) != -1){
+		for (i = 0; i < nelem(dispatch); i++)
+			if (b->op == dispatch[i].op)
+				(*dispatch[i].func)(b);
+
+		if (Debug && i >= nelem(dispatch)){
+			Bprint(bo, "op=0x%x len=%d\n", b->op, b->len);
+			xd(b);
+		}
+		skip(b, b->len);
+	}
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-nta] [-d delim] file.xls\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	int i;
+	Biobuf bin, bout, *bp;
+	
+	ARGBEGIN{
+	case 'n':
+		Nopad = 1;
+		break;
+	case 't':
+		Trunc = 1;
+		break;
+	case 'a':
+		All = 1;
+		break;
+	case 'd':
+		Delim = EARGF(usage());
+		break;
+	case 'D':
+		Debug = 1;
+		break;
+	default:
+		usage();
+		break;
+	}ARGEND;
+
+	if (argc != 1)
+		usage();
+
+	bo = &bout;
+	quotefmtinstall();
+	Binit(bo, OWRITE, 1);
+
+	if(argc > 0) {
+		for(i = 0; i < argc; i++){
+			if ((bp = Bopen(argv[i], OREAD)) == nil)
+				sysfatal("%s cannot open - %r\n", argv[i]);
+			xls2csv(bp);
+			Bterm(bp);
+		}
+	} else {
+		Binit(&bin, 0, OREAD);
+		xls2csv(&bin);
+	}
+	exits(0);
+}
+

+ 44 - 0
sys/src/cmd/upas/smtp/mxdial.c

@@ -265,3 +265,47 @@ dial_string_parse(char *str, DS *ds)
 	if(ds->service)
 		*ds->service++ = 0;
 }
+
+char *
+expand_meta(char *addr)
+{
+	DS ds;
+	int fd, n;
+	char *p, cs[128];
+	static char buf[1024];
+
+	dial_string_parse(addr, &ds);
+
+	if (*ds.host != '$')
+		return addr;
+	if (! ds.netdir)
+		ds.netdir = "/net";
+
+	snprint(cs, sizeof(cs), "%s/cs", ds.netdir);
+	if ((fd = open(cs, ORDWR)) == -1){
+		syslog(0, "smtp", "cannot open cs: %r", cs);
+		return addr;
+	}
+
+	snprint(buf, sizeof(buf), "!ipinfo %s", ds.host+1);	// +1 to skip $
+	if(write(fd, buf, strlen(buf)) <= 0){
+		syslog(0, "smtp", "%s to %s - write failed: %r", buf, cs);
+		close(fd);
+		return addr;
+	}
+
+	seek(fd, 0, 0);
+	if((n = read(fd, buf, sizeof(buf)-1)) < 0){
+		syslog(0, "smtp", "%s - read failed: %r", cs);
+		close(fd);
+		return addr;
+	}
+	close(fd);
+
+	buf[n] = 0;
+	if((p = strchr(buf, '=')) == nil){
+		syslog(0, "smtp", "%q from %s - bad response: %r", buf, cs);
+		return addr;
+	}
+	return p+1; 	// +1 to skip =
+}

+ 55 - 26
sys/src/cmd/upas/smtp/smtp.c

@@ -7,7 +7,7 @@
 
 static	char*	connect(char*);
 static	char*	dotls(char*);
-static	char*	doauth(void);
+static	char*	doauth(char*);
 char*	hello(char*, int);
 char*	mailfrom(char*);
 char*	rcptto(char*);
@@ -238,11 +238,9 @@ main(int argc, char **argv)
 	}
 
 	rv = data(from, &bfile);
-if(debug) fprint(2, "data rv %s\n", rv);
 	if(rv != 0)
 		goto error;
 	quit(0);
-if(debug) fprint(2, "rcvrs %d ok %d\n", rcvrs, ok);
 	if(rcvrs == ok)
 		exits(0);
 
@@ -267,10 +265,8 @@ error:
 		ping ? "ping" : "delivery",
 		addr, s_to_c(reply));
 	fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply));
-if(debug) fprint(2, "errors %s\n", rv);
 	if(!filter)
 		quit(rv);
-if(debug) fprint(2, "exits %s\n", rv);
 	exits(rv);
 }
 
@@ -367,7 +363,6 @@ dotls(char *me)
 	 */
 	Binit(&bin, fd, OREAD);
 	fd = dup(fd, -1);
-if(debug)fprint(2, "bout fd = %d\n", fd);
 	Binit(&bout, fd, OWRITE);
 
 	syslog(0, "smtp", "started TLS to %q", ddomain);
@@ -375,34 +370,68 @@ if(debug)fprint(2, "bout fd = %d\n", fd);
 }
 
 static char *
-doauth(void)
+doauth(char *methods)
 {
-	char *buf, *base64;
+	char *sys, *buf, *base64;
 	UserPasswd *p;
 	int n;
 
+	sys = expand_meta(ddomain);
+	//fprint(2, "expand address %s -> %s\n", ddomain, sys);
+
 	if(user != nil)
 		p = auth_getuserpasswd(nil,
-	  	  "proto=pass service=smtp server=%q user=%q", ddomain, user);
+	  	  "proto=pass service=smtp server=%q user=%q", sys, user);
 	else
 		p = auth_getuserpasswd(nil,
-	  	  "proto=pass service=smtp server=%q", ddomain);
+	  	  "proto=pass service=smtp server=%q", sys);
 	if (p == nil)
 		return Giveup;
-	n = strlen(p->user) + strlen(p->passwd) + 3;
-	buf = malloc(n);
-	base64 = malloc(2 * n);
-	if (buf == nil || base64 == nil) {
+
+	if (strstr(methods, "LOGIN")){
+		dBprint("AUTH LOGIN\r\n");
+		if (getreply() != 3)
+			return Retry;
+
+		n = strlen(p->user);
+		base64 = malloc(2*n);
+		if (base64 == nil)
+			return Retry;	/* Out of memory */
+		enc64(base64, 2*n, (uchar *)p->user, n);
+		dBprint("%s\r\n", base64);
+		if (getreply() != 3)
+			return Retry;
+
+		n = strlen(p->passwd);
+		base64 = malloc(2*n);
+		if (base64 == nil)
+			return Retry;	/* Out of memory */
+		enc64(base64, 2*n, (uchar *)p->passwd, n);
+		dBprint("%s\r\n", base64);
+		if (getreply() != 2)
+			return Retry;
+
+		free(base64);
+	}
+	else
+	if (strstr(methods, "PLAIN")){
+		n = strlen(p->user) + strlen(p->passwd) + 3;
+		buf = malloc(n);
+		base64 = malloc(2 * n);
+		if (buf == nil || base64 == nil) {
+			free(buf);
+			return Retry;	/* Out of memory */
+		}
+		snprint(buf, n, "%c%s%c%s", 0, p->user, 0, p->passwd);
+		enc64(base64, 2 * n, (uchar *)buf, n - 1);
 		free(buf);
-		return Retry;	/* Out of memory */
+		dBprint("AUTH PLAIN %s\r\n", base64);
+		free(base64);
+		if (getreply() != 2)
+			return Retry;
 	}
-	snprint(buf, n, "%c%s%c%s", 0, p->user, 0, p->passwd);
-	enc64(base64, 2 * n, (uchar *)buf, n - 1);
-	free(buf);
-	dBprint("AUTH PLAIN %s\r\n", base64);
-	free(base64);
-	if (getreply() != 2)
-		return Retry;
+	else
+		return "No supported AUTH method";
 	return(0);
 }
 
@@ -411,7 +440,7 @@ hello(char *me, int encrypted)
 {
 	int ehlo;
 	String *r;
-	char *s, *t;
+	char *ret, *s, *t;
 
 	if (!encrypted)
 		switch(getreply()){
@@ -458,10 +487,10 @@ hello(char *me, int encrypted)
 		}
 		if(tryauth && (encrypted || insecure) &&
 		    (strncmp(s, "250 AUTH", strlen("250 AUTH")) == 0 ||
-		     strncmp(s, "250-AUTH", strlen("250 AUTH")) == 0) &&
-		    strstr(s, "PLAIN") != nil){
+		     strncmp(s, "250-AUTH", strlen("250 AUTH")) == 0)){
+			ret = doauth(s + strlen("250 AUTH "));
 			s_free(r);
-			return(doauth());
+			return ret;
 		}
 	}
 	s_free(r);

+ 1 - 0
sys/src/cmd/upas/smtp/smtp.h

@@ -47,3 +47,4 @@ String*	yywhite(void);
 Node*	whiten(Node*);
 void	yycleanup(void);
 int	mxdial(char*, char*, char*);
+char*	expand_meta(char *);

+ 1 - 1
sys/src/mkfile.proto

@@ -4,7 +4,7 @@
 
 OS=578qv
 CPUS=arm alpha 386 power mips
-CFLAGS=-FTVw
+CFLAGS=-FVw
 LEX=lex
 YACC=yacc
 MK=/bin/mk

+ 1 - 0
usr/glenda/lib/profile

@@ -5,6 +5,7 @@ if(! syscall create /tmp/xxx 1 0666 >[2]/dev/null)
 	ramfs	# in case we're running off a cd
 font = /lib/font/bit/pelm/euro.9.font
 upas/fs
+fn cd { builtin cd $* && awd }  # for acme
 switch($service){
 case terminal
 	plumber