Browse Source

Plan 9 from Bell Labs 2007-06-11

David du Colombier 17 years ago
parent
commit
0c7a213a77

+ 36 - 36
dist/replica/_plan9.db

@@ -19,8 +19,8 @@
 386/bin/8l - 775 sys sys 1148500567 115711
 386/bin/9660srv - 775 sys sys 1168402261 104975
 386/bin/aan - 775 sys sys 1179548013 129834
-386/bin/acid - 775 sys sys 1179548014 405147
-386/bin/acme - 775 sys sys 1179548014 430944
+386/bin/acid - 775 sys sys 1181507261 405141
+386/bin/acme - 775 sys sys 1181507262 430979
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1173754547 134719
 386/bin/ape/cc - 775 sys sys 1168402263 70642
@@ -37,7 +37,7 @@
 386/bin/ape/stty - 775 sys sys 1148500571 41080
 386/bin/ape/tar - 775 sys sys 1168402264 62184
 386/bin/ape/uname - 775 sys sys 1173754552 134895
-386/bin/aquarela - 775 sys sys 1179548015 337756
+386/bin/aquarela - 775 sys sys 1181507262 337750
 386/bin/ar - 775 sys sys 1178939751 114363
 386/bin/archfs - 775 sys sys 1179372067 146788
 386/bin/ascii - 775 sys sys 1168402265 64884
@@ -123,13 +123,13 @@
 386/bin/aux/mswordstrings - 775 sys sys 1168402283 65541
 386/bin/aux/na - 775 sys sys 1168402284 154423
 386/bin/aux/nfsmount - 775 sys sys 1179548018 233229
-386/bin/aux/nfsserver - 775 sys sys 1179548018 184499
+386/bin/aux/nfsserver - 775 sys sys 1181507263 184493
 386/bin/aux/olefs - 775 sys sys 1179372075 148111
 386/bin/aux/p9bitpost - 775 sys sys 1104121982 127974
 386/bin/aux/pcmcia - 775 sys sys 1148500601 46940
-386/bin/aux/pcnfsd - 775 sys sys 1179548019 128333
+386/bin/aux/pcnfsd - 775 sys sys 1181507263 128327
 386/bin/aux/portmap - 775 sys sys 1179548019 142747
-386/bin/aux/portmapper - 775 sys sys 1179548020 127412
+386/bin/aux/portmapper - 775 sys sys 1181507264 127406
 386/bin/aux/postgif - 775 sys sys 1087442507 175380
 386/bin/aux/postprint - 775 sys sys 1087442507 160041
 386/bin/aux/postreverse - 775 sys sys 1087442508 164726
@@ -172,14 +172,14 @@
 386/bin/bunzip2 - 775 sys sys 1168402292 97734
 386/bin/bzip2 - 775 sys sys 1178568261 112709
 386/bin/cal - 775 sys sys 1178568261 66661
-386/bin/calendar - 775 sys sys 1179548022 79060
+386/bin/calendar - 775 sys sys 1181507264 79054
 386/bin/cat - 775 sys sys 1148500611 37482
 386/bin/cb - 775 sys sys 1168402293 77628
 386/bin/cdfs - 775 sys sys 1179372081 166023
 386/bin/cfs - 775 sys sys 1179372081 130255
 386/bin/chgrp - 775 sys sys 1168402294 59522
 386/bin/chmod - 775 sys sys 1168402294 62518
-386/bin/cifscmd - 775 sys sys 1179548023 348594
+386/bin/cifscmd - 775 sys sys 1181507265 348588
 386/bin/cleanname - 775 sys sys 1168402295 58541
 386/bin/clock - 775 sys sys 1179372082 157340
 386/bin/cmp - 775 sys sys 1157597609 40658
@@ -203,7 +203,7 @@
 386/bin/dial/drain - 775 sys sys 1068385869 4120
 386/bin/dial/expect - 775 sys sys 1168402300 60316
 386/bin/dial/pass - 775 sys sys 1148500621 38849
-386/bin/dict - 775 sys sys 1179548024 187908
+386/bin/dict - 775 sys sys 1181507265 187900
 386/bin/diff - 775 sys sys 1168402301 85316
 386/bin/disk - 20000000775 sys sys 984788664 0
 386/bin/disk/dump9660 - 775 sys sys 1178568266 151103
@@ -224,12 +224,12 @@
 386/bin/du - 775 sys sys 1179777650 76275
 386/bin/echo - 775 sys sys 1168402304 57592
 386/bin/ecp - 775 sys sys 1179777651 72588
-386/bin/ed - 775 sys sys 1179548024 93463
+386/bin/ed - 775 sys sys 1181507265 93455
 386/bin/eqn - 775 sys sys 1173754555 244858
 386/bin/execnet - 775 sys sys 1179548024 176802
-386/bin/exportfs - 775 sys sys 1179548025 161222
+386/bin/exportfs - 775 sys sys 1181507266 161216
 386/bin/ext2srv - 775 sys sys 1179372085 178481
-386/bin/faces - 775 sys sys 1179548025 193271
+386/bin/faces - 775 sys sys 1181507266 193265
 386/bin/factor - 775 sys sys 1168402307 61699
 386/bin/fcp - 775 sys sys 1168402307 82433
 386/bin/file - 775 sys sys 1178939751 128125
@@ -278,7 +278,7 @@
 386/bin/history - 775 sys sys 1178568279 74241
 386/bin/hoc - 775 sys sys 1172808058 100101
 386/bin/html2ms - 775 sys sys 1168402315 66321
-386/bin/htmlfmt - 775 sys sys 1179548026 163407
+386/bin/htmlfmt - 775 sys sys 1181507267 163401
 386/bin/htmlroff - 775 sys sys 1178568280 146978
 386/bin/ico - 775 sys sys 1179372092 162180
 386/bin/iconv - 775 sys sys 1168402316 113629
@@ -290,7 +290,7 @@
 386/bin/ip/dhcpclient - 775 sys sys 1178568281 92992
 386/bin/ip/dhcpd - 775 sys sys 1179458669 149879
 386/bin/ip/dhcpleases - 775 sys sys 1178568281 85069
-386/bin/ip/ftpd - 775 sys sys 1179548027 170568
+386/bin/ip/ftpd - 775 sys sys 1181507267 170562
 386/bin/ip/gping - 775 sys sys 1179372093 182147
 386/bin/ip/hogports - 775 sys sys 1148500655 42914
 386/bin/ip/httpd - 20000000775 sys sys 1068385801 0
@@ -300,7 +300,7 @@
 386/bin/ip/httpd/netlib_find - 775 sys sys 1178568285 116797
 386/bin/ip/httpd/netlib_history - 775 sys sys 1178568285 115589
 386/bin/ip/httpd/save - 775 sys sys 1178568285 132389
-386/bin/ip/httpd/webls - 775 sys sys 1179548027 132464
+386/bin/ip/httpd/webls - 775 sys sys 1181507267 132458
 386/bin/ip/httpd/wikipost - 775 sys sys 1178568286 113828
 386/bin/ip/httpfile - 775 sys sys 1179548028 283978
 386/bin/ip/imap4d - 775 sys sys 1179372095 236829
@@ -331,7 +331,7 @@
 386/bin/ls - 775 sys sys 1178568291 81002
 386/bin/mc - 775 sys sys 1179372098 134354
 386/bin/md5sum - 775 sys sys 1168402334 61498
-386/bin/mk - 775 sys sys 1179548029 143426
+386/bin/mk - 775 sys sys 1181507268 143420
 386/bin/mkdir - 775 sys sys 1168402334 61205
 386/bin/mkpaqfs - 775 sys sys 1178568292 93268
 386/bin/mntgen - 775 sys sys 1179372098 144046
@@ -369,7 +369,7 @@
 386/bin/pipefile - 775 sys sys 1148500683 39431
 386/bin/plot - 775 sys sys 1179372101 222763
 386/bin/plumb - 775 sys sys 1176520491 69487
-386/bin/plumber - 775 sys sys 1179548031 170952
+386/bin/plumber - 775 sys sys 1181507268 170946
 386/bin/png - 775 sys sys 1179372101 164630
 386/bin/ppm - 775 sys sys 1179372101 149813
 386/bin/pr - 775 sys sys 1178568298 76251
@@ -396,11 +396,11 @@
 386/bin/rio - 775 sys sys 1179604582 312202
 386/bin/rm - 775 sys sys 1168402347 61568
 386/bin/rx - 775 sys sys 1179372103 82274
-386/bin/sam - 775 sys sys 1168633586 159364
+386/bin/sam - 775 sys sys 1181507269 159317
 386/bin/scat - 775 sys sys 1179372104 284884
 386/bin/scp - 775 sys sys 1178568301 152318
-386/bin/scuzz - 775 sys sys 1178422014 115094
-386/bin/sed - 775 sys sys 1179548032 89954
+386/bin/scuzz - 775 sys sys 1181507269 115314
+386/bin/sed - 775 sys sys 1181507269 89946
 386/bin/seq - 775 sys sys 1162241047 38441
 386/bin/sha1sum - 775 sys sys 1168402348 61366
 386/bin/size - 775 sys sys 1178939753 79772
@@ -408,10 +408,10 @@
 386/bin/snap - 775 sys sys 1178939753 316147
 386/bin/snapfs - 775 sys sys 1179372105 390366
 386/bin/sniffer - 775 sys sys 1038443185 99028
-386/bin/snoopy - 775 sys sys 1178568303 185244
+386/bin/snoopy - 775 sys sys 1181507270 189844
 386/bin/sort - 775 sys sys 1178568303 81057
 386/bin/spin - 775 sys sys 1176520498 760856
-386/bin/split - 775 sys sys 1179548032 75817
+386/bin/split - 775 sys sys 1181507270 75811
 386/bin/srv - 775 sys sys 1179372105 82797
 386/bin/srvfs - 775 sys sys 1162241047 40169
 386/bin/srvold9p - 775 sys sys 1176520499 130362
@@ -456,27 +456,27 @@
 386/bin/upas/aliasmail - 775 sys sys 1178568309 104105
 386/bin/upas/bayes - 775 sys sys 1178568309 73372
 386/bin/upas/deliver - 775 sys sys 1179976975 99212
-386/bin/upas/filter - 775 sys sys 1179548034 146753
+386/bin/upas/filter - 775 sys sys 1181507270 146747
 386/bin/upas/fs - 775 sys sys 1178568311 331725
 386/bin/upas/isspam - 775 sys sys 1064598349 38
-386/bin/upas/list - 775 sys sys 1179548035 83036
+386/bin/upas/list - 775 sys sys 1181507270 83030
 386/bin/upas/marshal - 775 sys sys 1179113026 132974
 386/bin/upas/ml - 775 sys sys 1178568312 122913
 386/bin/upas/mlmgr - 775 sys sys 1178568312 103536
 386/bin/upas/mlowner - 775 sys sys 1177617496 92263
 386/bin/upas/msgcat - 775 sys sys 1064598353 38
 386/bin/upas/msgtok - 775 sys sys 1176520508 76758
-386/bin/upas/nedmail - 775 sys sys 1179976975 156013
+386/bin/upas/nedmail - 775 sys sys 1181507271 156007
 386/bin/upas/pop3 - 775 sys sys 1179372109 261615
 386/bin/upas/qer - 775 sys sys 1178568313 99195
 386/bin/upas/ratfs - 775 sys sys 1178568314 110177
 386/bin/upas/runq - 775 sys sys 1178568314 112842
-386/bin/upas/scanmail - 775 sys sys 1179548035 128213
-386/bin/upas/send - 775 sys sys 1179548036 192180
+386/bin/upas/scanmail - 775 sys sys 1181507271 128207
+386/bin/upas/send - 775 sys sys 1181507272 192174
 386/bin/upas/smtp - 775 sys sys 1178568316 274783
 386/bin/upas/smtpd - 775 sys sys 1179372110 331146
 386/bin/upas/spam - 775 sys sys 1064598366 36
-386/bin/upas/testscan - 775 sys sys 1179548036 83864
+386/bin/upas/testscan - 775 sys sys 1181507272 83858
 386/bin/upas/token - 775 sys sys 1178568317 76393
 386/bin/upas/unesc - 775 sys sys 1176520512 60137
 386/bin/upas/unspam - 775 sys sys 1064598367 38
@@ -514,10 +514,10 @@
 386/bin/vtdump - 775 sys sys 1178568328 160252
 386/bin/wc - 775 sys sys 1148500701 41191
 386/bin/webcookies - 775 sys sys 1179372114 166178
-386/bin/webfs - 775 sys sys 1179548039 360394
+386/bin/webfs - 775 sys sys 1181507272 360388
 386/bin/webfsget - 775 sys sys 1148500702 39177
 386/bin/wikifs - 775 sys sys 1179372115 203019
-386/bin/winwatch - 775 sys sys 1179548039 155326
+386/bin/winwatch - 775 sys sys 1181507273 155320
 386/bin/x.echo - 775 sys sys 1168402359 57592
 386/bin/xd - 775 sys sys 1168402359 64279
 386/bin/xmr - 775 sys sys 1148500703 40192
@@ -571,7 +571,7 @@
 386/lib/libmp.a - 664 sys sys 1181332906 79978
 386/lib/libndb.a - 664 sys sys 1178826955 64470
 386/lib/libplumb.a - 664 sys sys 1168402370 19408
-386/lib/libregexp.a - 664 sys sys 1179548041 37414
+386/lib/libregexp.a - 664 sys sys 1181507273 37290
 386/lib/libscribble.a - 664 sys sys 1175972562 107238
 386/lib/libsec.a - 664 sys sys 1181332908 646724
 386/lib/libstdio.a - 664 sys sys 1176432133 126062
@@ -7643,7 +7643,7 @@ sys/man/3/ether - 664 sys sys 1178597986 2890
 sys/man/3/floppy - 664 sys sys 954378905 881
 sys/man/3/fs - 664 sys sys 1175145095 3147
 sys/man/3/i82365 - 664 sys sys 954378906 884
-sys/man/3/ip - 664 sys sys 1179708346 24886
+sys/man/3/ip - 664 sys sys 1181506841 24876
 sys/man/3/kbmap - 664 sys sys 1131110122 1732
 sys/man/3/kprof - 664 sys sys 1018029972 1377
 sys/man/3/loopback - 664 sys sys 964662153 1995
@@ -9121,7 +9121,7 @@ sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
 sys/src/boot/pc/ether8169.c - 664 sys sys 1156429147 21582
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether82563.c - 664 sys sys 1178926666 24957
+sys/src/boot/pc/ether82563.c - 664 sys sys 1181517000 25452
 sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1112382847 16209
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392
@@ -9132,7 +9132,7 @@ sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherga620.c - 664 sys sys 1175289484 27168
 sys/src/boot/pc/etherga620fw.h - 664 sys sys 1174080072 222295
 sys/src/boot/pc/etherif.h - 664 sys sys 1174077279 1338
-sys/src/boot/pc/etherigbe.c - 664 sys sys 1140710606 40769
+sys/src/boot/pc/etherigbe.c - 664 sys sys 1181515261 41262
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
@@ -14247,9 +14247,9 @@ 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 1143759341 20123
 sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1108827986 1270
-sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1161308327 31702
+sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1181513473 32835
 sys/src/cmd/upas/smtp/smtpd.h - 664 sys sys 1067722781 1111
-sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1143670612 6961
+sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1181508390 6924
 sys/src/cmd/upas/smtp/spam.c - 664 sys sys 1139699502 10238
 sys/src/cmd/upas/unesc - 20000000775 sys sys 1075080255 0
 sys/src/cmd/upas/unesc/mkfile - 664 sys sys 1173383407 142

+ 36 - 36
dist/replica/plan9.db

@@ -19,8 +19,8 @@
 386/bin/8l - 775 sys sys 1148500567 115711
 386/bin/9660srv - 775 sys sys 1168402261 104975
 386/bin/aan - 775 sys sys 1179548013 129834
-386/bin/acid - 775 sys sys 1179548014 405147
-386/bin/acme - 775 sys sys 1179548014 430944
+386/bin/acid - 775 sys sys 1181507261 405141
+386/bin/acme - 775 sys sys 1181507262 430979
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1173754547 134719
 386/bin/ape/cc - 775 sys sys 1168402263 70642
@@ -37,7 +37,7 @@
 386/bin/ape/stty - 775 sys sys 1148500571 41080
 386/bin/ape/tar - 775 sys sys 1168402264 62184
 386/bin/ape/uname - 775 sys sys 1173754552 134895
-386/bin/aquarela - 775 sys sys 1179548015 337756
+386/bin/aquarela - 775 sys sys 1181507262 337750
 386/bin/ar - 775 sys sys 1178939751 114363
 386/bin/archfs - 775 sys sys 1179372067 146788
 386/bin/ascii - 775 sys sys 1168402265 64884
@@ -123,13 +123,13 @@
 386/bin/aux/mswordstrings - 775 sys sys 1168402283 65541
 386/bin/aux/na - 775 sys sys 1168402284 154423
 386/bin/aux/nfsmount - 775 sys sys 1179548018 233229
-386/bin/aux/nfsserver - 775 sys sys 1179548018 184499
+386/bin/aux/nfsserver - 775 sys sys 1181507263 184493
 386/bin/aux/olefs - 775 sys sys 1179372075 148111
 386/bin/aux/p9bitpost - 775 sys sys 1104121982 127974
 386/bin/aux/pcmcia - 775 sys sys 1148500601 46940
-386/bin/aux/pcnfsd - 775 sys sys 1179548019 128333
+386/bin/aux/pcnfsd - 775 sys sys 1181507263 128327
 386/bin/aux/portmap - 775 sys sys 1179548019 142747
-386/bin/aux/portmapper - 775 sys sys 1179548020 127412
+386/bin/aux/portmapper - 775 sys sys 1181507264 127406
 386/bin/aux/postgif - 775 sys sys 1087442507 175380
 386/bin/aux/postprint - 775 sys sys 1087442507 160041
 386/bin/aux/postreverse - 775 sys sys 1087442508 164726
@@ -172,14 +172,14 @@
 386/bin/bunzip2 - 775 sys sys 1168402292 97734
 386/bin/bzip2 - 775 sys sys 1178568261 112709
 386/bin/cal - 775 sys sys 1178568261 66661
-386/bin/calendar - 775 sys sys 1179548022 79060
+386/bin/calendar - 775 sys sys 1181507264 79054
 386/bin/cat - 775 sys sys 1148500611 37482
 386/bin/cb - 775 sys sys 1168402293 77628
 386/bin/cdfs - 775 sys sys 1179372081 166023
 386/bin/cfs - 775 sys sys 1179372081 130255
 386/bin/chgrp - 775 sys sys 1168402294 59522
 386/bin/chmod - 775 sys sys 1168402294 62518
-386/bin/cifscmd - 775 sys sys 1179548023 348594
+386/bin/cifscmd - 775 sys sys 1181507265 348588
 386/bin/cleanname - 775 sys sys 1168402295 58541
 386/bin/clock - 775 sys sys 1179372082 157340
 386/bin/cmp - 775 sys sys 1157597609 40658
@@ -203,7 +203,7 @@
 386/bin/dial/drain - 775 sys sys 1068385869 4120
 386/bin/dial/expect - 775 sys sys 1168402300 60316
 386/bin/dial/pass - 775 sys sys 1148500621 38849
-386/bin/dict - 775 sys sys 1179548024 187908
+386/bin/dict - 775 sys sys 1181507265 187900
 386/bin/diff - 775 sys sys 1168402301 85316
 386/bin/disk - 20000000775 sys sys 984788664 0
 386/bin/disk/dump9660 - 775 sys sys 1178568266 151103
@@ -224,12 +224,12 @@
 386/bin/du - 775 sys sys 1179777650 76275
 386/bin/echo - 775 sys sys 1168402304 57592
 386/bin/ecp - 775 sys sys 1179777651 72588
-386/bin/ed - 775 sys sys 1179548024 93463
+386/bin/ed - 775 sys sys 1181507265 93455
 386/bin/eqn - 775 sys sys 1173754555 244858
 386/bin/execnet - 775 sys sys 1179548024 176802
-386/bin/exportfs - 775 sys sys 1179548025 161222
+386/bin/exportfs - 775 sys sys 1181507266 161216
 386/bin/ext2srv - 775 sys sys 1179372085 178481
-386/bin/faces - 775 sys sys 1179548025 193271
+386/bin/faces - 775 sys sys 1181507266 193265
 386/bin/factor - 775 sys sys 1168402307 61699
 386/bin/fcp - 775 sys sys 1168402307 82433
 386/bin/file - 775 sys sys 1178939751 128125
@@ -278,7 +278,7 @@
 386/bin/history - 775 sys sys 1178568279 74241
 386/bin/hoc - 775 sys sys 1172808058 100101
 386/bin/html2ms - 775 sys sys 1168402315 66321
-386/bin/htmlfmt - 775 sys sys 1179548026 163407
+386/bin/htmlfmt - 775 sys sys 1181507267 163401
 386/bin/htmlroff - 775 sys sys 1178568280 146978
 386/bin/ico - 775 sys sys 1179372092 162180
 386/bin/iconv - 775 sys sys 1168402316 113629
@@ -290,7 +290,7 @@
 386/bin/ip/dhcpclient - 775 sys sys 1178568281 92992
 386/bin/ip/dhcpd - 775 sys sys 1179458669 149879
 386/bin/ip/dhcpleases - 775 sys sys 1178568281 85069
-386/bin/ip/ftpd - 775 sys sys 1179548027 170568
+386/bin/ip/ftpd - 775 sys sys 1181507267 170562
 386/bin/ip/gping - 775 sys sys 1179372093 182147
 386/bin/ip/hogports - 775 sys sys 1148500655 42914
 386/bin/ip/httpd - 20000000775 sys sys 1068385801 0
@@ -300,7 +300,7 @@
 386/bin/ip/httpd/netlib_find - 775 sys sys 1178568285 116797
 386/bin/ip/httpd/netlib_history - 775 sys sys 1178568285 115589
 386/bin/ip/httpd/save - 775 sys sys 1178568285 132389
-386/bin/ip/httpd/webls - 775 sys sys 1179548027 132464
+386/bin/ip/httpd/webls - 775 sys sys 1181507267 132458
 386/bin/ip/httpd/wikipost - 775 sys sys 1178568286 113828
 386/bin/ip/httpfile - 775 sys sys 1179548028 283978
 386/bin/ip/imap4d - 775 sys sys 1179372095 236829
@@ -331,7 +331,7 @@
 386/bin/ls - 775 sys sys 1178568291 81002
 386/bin/mc - 775 sys sys 1179372098 134354
 386/bin/md5sum - 775 sys sys 1168402334 61498
-386/bin/mk - 775 sys sys 1179548029 143426
+386/bin/mk - 775 sys sys 1181507268 143420
 386/bin/mkdir - 775 sys sys 1168402334 61205
 386/bin/mkpaqfs - 775 sys sys 1178568292 93268
 386/bin/mntgen - 775 sys sys 1179372098 144046
@@ -369,7 +369,7 @@
 386/bin/pipefile - 775 sys sys 1148500683 39431
 386/bin/plot - 775 sys sys 1179372101 222763
 386/bin/plumb - 775 sys sys 1176520491 69487
-386/bin/plumber - 775 sys sys 1179548031 170952
+386/bin/plumber - 775 sys sys 1181507268 170946
 386/bin/png - 775 sys sys 1179372101 164630
 386/bin/ppm - 775 sys sys 1179372101 149813
 386/bin/pr - 775 sys sys 1178568298 76251
@@ -396,11 +396,11 @@
 386/bin/rio - 775 sys sys 1179604582 312202
 386/bin/rm - 775 sys sys 1168402347 61568
 386/bin/rx - 775 sys sys 1179372103 82274
-386/bin/sam - 775 sys sys 1168633586 159364
+386/bin/sam - 775 sys sys 1181507269 159317
 386/bin/scat - 775 sys sys 1179372104 284884
 386/bin/scp - 775 sys sys 1178568301 152318
-386/bin/scuzz - 775 sys sys 1178422014 115094
-386/bin/sed - 775 sys sys 1179548032 89954
+386/bin/scuzz - 775 sys sys 1181507269 115314
+386/bin/sed - 775 sys sys 1181507269 89946
 386/bin/seq - 775 sys sys 1162241047 38441
 386/bin/sha1sum - 775 sys sys 1168402348 61366
 386/bin/size - 775 sys sys 1178939753 79772
@@ -408,10 +408,10 @@
 386/bin/snap - 775 sys sys 1178939753 316147
 386/bin/snapfs - 775 sys sys 1179372105 390366
 386/bin/sniffer - 775 sys sys 1038443185 99028
-386/bin/snoopy - 775 sys sys 1178568303 185244
+386/bin/snoopy - 775 sys sys 1181507270 189844
 386/bin/sort - 775 sys sys 1178568303 81057
 386/bin/spin - 775 sys sys 1176520498 760856
-386/bin/split - 775 sys sys 1179548032 75817
+386/bin/split - 775 sys sys 1181507270 75811
 386/bin/srv - 775 sys sys 1179372105 82797
 386/bin/srvfs - 775 sys sys 1162241047 40169
 386/bin/srvold9p - 775 sys sys 1176520499 130362
@@ -456,27 +456,27 @@
 386/bin/upas/aliasmail - 775 sys sys 1178568309 104105
 386/bin/upas/bayes - 775 sys sys 1178568309 73372
 386/bin/upas/deliver - 775 sys sys 1179976975 99212
-386/bin/upas/filter - 775 sys sys 1179548034 146753
+386/bin/upas/filter - 775 sys sys 1181507270 146747
 386/bin/upas/fs - 775 sys sys 1178568311 331725
 386/bin/upas/isspam - 775 sys sys 1064598349 38
-386/bin/upas/list - 775 sys sys 1179548035 83036
+386/bin/upas/list - 775 sys sys 1181507270 83030
 386/bin/upas/marshal - 775 sys sys 1179113026 132974
 386/bin/upas/ml - 775 sys sys 1178568312 122913
 386/bin/upas/mlmgr - 775 sys sys 1178568312 103536
 386/bin/upas/mlowner - 775 sys sys 1177617496 92263
 386/bin/upas/msgcat - 775 sys sys 1064598353 38
 386/bin/upas/msgtok - 775 sys sys 1176520508 76758
-386/bin/upas/nedmail - 775 sys sys 1179976975 156013
+386/bin/upas/nedmail - 775 sys sys 1181507271 156007
 386/bin/upas/pop3 - 775 sys sys 1179372109 261615
 386/bin/upas/qer - 775 sys sys 1178568313 99195
 386/bin/upas/ratfs - 775 sys sys 1178568314 110177
 386/bin/upas/runq - 775 sys sys 1178568314 112842
-386/bin/upas/scanmail - 775 sys sys 1179548035 128213
-386/bin/upas/send - 775 sys sys 1179548036 192180
+386/bin/upas/scanmail - 775 sys sys 1181507271 128207
+386/bin/upas/send - 775 sys sys 1181507272 192174
 386/bin/upas/smtp - 775 sys sys 1178568316 274783
 386/bin/upas/smtpd - 775 sys sys 1179372110 331146
 386/bin/upas/spam - 775 sys sys 1064598366 36
-386/bin/upas/testscan - 775 sys sys 1179548036 83864
+386/bin/upas/testscan - 775 sys sys 1181507272 83858
 386/bin/upas/token - 775 sys sys 1178568317 76393
 386/bin/upas/unesc - 775 sys sys 1176520512 60137
 386/bin/upas/unspam - 775 sys sys 1064598367 38
@@ -514,10 +514,10 @@
 386/bin/vtdump - 775 sys sys 1178568328 160252
 386/bin/wc - 775 sys sys 1148500701 41191
 386/bin/webcookies - 775 sys sys 1179372114 166178
-386/bin/webfs - 775 sys sys 1179548039 360394
+386/bin/webfs - 775 sys sys 1181507272 360388
 386/bin/webfsget - 775 sys sys 1148500702 39177
 386/bin/wikifs - 775 sys sys 1179372115 203019
-386/bin/winwatch - 775 sys sys 1179548039 155326
+386/bin/winwatch - 775 sys sys 1181507273 155320
 386/bin/x.echo - 775 sys sys 1168402359 57592
 386/bin/xd - 775 sys sys 1168402359 64279
 386/bin/xmr - 775 sys sys 1148500703 40192
@@ -571,7 +571,7 @@
 386/lib/libmp.a - 664 sys sys 1181332906 79978
 386/lib/libndb.a - 664 sys sys 1178826955 64470
 386/lib/libplumb.a - 664 sys sys 1168402370 19408
-386/lib/libregexp.a - 664 sys sys 1179548041 37414
+386/lib/libregexp.a - 664 sys sys 1181507273 37290
 386/lib/libscribble.a - 664 sys sys 1175972562 107238
 386/lib/libsec.a - 664 sys sys 1181332908 646724
 386/lib/libstdio.a - 664 sys sys 1176432133 126062
@@ -7643,7 +7643,7 @@ sys/man/3/ether - 664 sys sys 1178597986 2890
 sys/man/3/floppy - 664 sys sys 954378905 881
 sys/man/3/fs - 664 sys sys 1175145095 3147
 sys/man/3/i82365 - 664 sys sys 954378906 884
-sys/man/3/ip - 664 sys sys 1179708346 24886
+sys/man/3/ip - 664 sys sys 1181506841 24876
 sys/man/3/kbmap - 664 sys sys 1131110122 1732
 sys/man/3/kprof - 664 sys sys 1018029972 1377
 sys/man/3/loopback - 664 sys sys 964662153 1995
@@ -9121,7 +9121,7 @@ sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
 sys/src/boot/pc/ether8169.c - 664 sys sys 1156429147 21582
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether82563.c - 664 sys sys 1178926666 24957
+sys/src/boot/pc/ether82563.c - 664 sys sys 1181517000 25452
 sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1112382847 16209
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392
@@ -9132,7 +9132,7 @@ sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherga620.c - 664 sys sys 1175289484 27168
 sys/src/boot/pc/etherga620fw.h - 664 sys sys 1174080072 222295
 sys/src/boot/pc/etherif.h - 664 sys sys 1174077279 1338
-sys/src/boot/pc/etherigbe.c - 664 sys sys 1140710606 40769
+sys/src/boot/pc/etherigbe.c - 664 sys sys 1181515261 41262
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
@@ -14247,9 +14247,9 @@ 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 1143759341 20123
 sys/src/cmd/upas/smtp/smtp.h - 664 sys sys 1108827986 1270
-sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1161308327 31702
+sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1181513473 32835
 sys/src/cmd/upas/smtp/smtpd.h - 664 sys sys 1067722781 1111
-sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1143670612 6961
+sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1181508390 6924
 sys/src/cmd/upas/smtp/spam.c - 664 sys sys 1139699502 10238
 sys/src/cmd/upas/unesc - 20000000775 sys sys 1075080255 0
 sys/src/cmd/upas/unesc/mkfile - 664 sys sys 1173383407 142

+ 36 - 0
dist/replica/plan9.log

@@ -49187,3 +49187,39 @@
 1181435423 3 c sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1181435454 38125
 1181437223 0 c sys/src/cmd/scuzz/scsireq.c - 664 sys sys 1181436637 13594
 1181437223 1 c sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1181436627 38286
+1181507439 0 c 386/bin/acid - 775 sys sys 1181507261 405141
+1181507439 1 c 386/bin/acme - 775 sys sys 1181507262 430979
+1181507439 2 c 386/bin/calendar - 775 sys sys 1181507264 79054
+1181507439 3 c 386/bin/dict - 775 sys sys 1181507265 187900
+1181507439 4 c 386/bin/ed - 775 sys sys 1181507265 93455
+1181507439 5 c 386/bin/exportfs - 775 sys sys 1181507266 161216
+1181507439 6 c 386/bin/faces - 775 sys sys 1181507266 193265
+1181507439 7 c 386/bin/htmlfmt - 775 sys sys 1181507267 163401
+1181507439 8 c 386/bin/mk - 775 sys sys 1181507268 143420
+1181507439 9 c 386/bin/plumber - 775 sys sys 1181507268 170946
+1181507439 10 c 386/bin/sam - 775 sys sys 1181507269 159317
+1181507439 11 c 386/bin/scuzz - 775 sys sys 1181507269 115314
+1181507439 12 c 386/bin/sed - 775 sys sys 1181507269 89946
+1181507439 13 c 386/bin/snoopy - 775 sys sys 1181507270 189844
+1181507439 14 c 386/bin/split - 775 sys sys 1181507270 75811
+1181507439 15 c 386/bin/webfs - 775 sys sys 1181507272 360388
+1181507439 16 c 386/bin/winwatch - 775 sys sys 1181507273 155320
+1181507439 17 c 386/bin/aquarela - 775 sys sys 1181507262 337750
+1181507439 18 c 386/bin/aux/nfsserver - 775 sys sys 1181507263 184493
+1181507439 19 c 386/bin/aux/pcnfsd - 775 sys sys 1181507263 128327
+1181507439 20 c 386/bin/aux/portmapper - 775 sys sys 1181507264 127406
+1181507439 21 c 386/bin/cifscmd - 775 sys sys 1181507265 348588
+1181507439 22 c 386/bin/ip/ftpd - 775 sys sys 1181507267 170562
+1181507439 23 c 386/bin/ip/httpd/webls - 775 sys sys 1181507267 132458
+1181507439 24 c 386/bin/upas/filter - 775 sys sys 1181507270 146747
+1181507439 25 c 386/bin/upas/list - 775 sys sys 1181507270 83030
+1181507439 26 c 386/bin/upas/nedmail - 775 sys sys 1181507271 156007
+1181507439 27 c 386/bin/upas/scanmail - 775 sys sys 1181507271 128207
+1181507439 28 c 386/bin/upas/send - 775 sys sys 1181507272 192174
+1181507439 29 c 386/bin/upas/testscan - 775 sys sys 1181507272 83858
+1181507439 30 c 386/lib/libregexp.a - 664 sys sys 1181507273 37290
+1181507439 31 c sys/man/3/ip - 664 sys sys 1181506841 24876
+1181509238 0 c sys/src/cmd/upas/smtp/smtpd.y - 664 sys sys 1181508390 6924
+1181514645 0 c sys/src/cmd/upas/smtp/smtpd.c - 664 sys sys 1181513473 32835
+1181516439 0 c sys/src/boot/pc/etherigbe.c - 664 sys sys 1181515261 41262
+1181518243 0 c sys/src/boot/pc/ether82563.c - 664 sys sys 1181517000 25452

+ 4 - 4
sys/man/3/ip

@@ -309,7 +309,7 @@ has 9 white-space-separated fields: device, mtu, local address,
 mask, remote or network address, packets in, packets out, input errors,
 output errors.  Each subsequent line contains all but the device and mtu.
 See
-.B readipifc
+.I readipifc
 in
 .IR ip (2).
 .SS "Routing
@@ -491,7 +491,7 @@ low level error messages and to implement
 IL provides a reliable datagram service for communication
 between Plan 9 machines but is now deprecated.
 GRE is a general encapsulation protocol.
-ESP is the encapsulation protocol for IPSEC.
+ESP is the encapsulation protocol for IPsec.
 .PP
 Each protocol is a subdirectory of the IP stack.
 The top level directory of each protocol contains a
@@ -942,8 +942,8 @@ IP mask.  In the case of
 .B iph
 and
 .BR proto ,
-both value and mask are strings of 2 character hexadecimal digits representing
-8 bit values.
+both value and mask are strings of 2 hexadecimal digits representing
+8-bit values.
 .PP
 A packet is delivered to only one filter.
 The filters are merged into a single comparison tree.

+ 154 - 125
sys/src/boot/pc/ether82563.c

@@ -1,6 +1,6 @@
 /*
  * bootstrap driver for
- * Intel 82563 Gigabit Ethernet Controller
+ * Intel 82563, 82571, 82573 Gigabit Ethernet Controllers
  */
 #include "u.h"
 #include "lib.h"
@@ -19,13 +19,13 @@
 
 /* from pci.c */
 enum
-{					/* command register (pcidev->pcr) */
-	IOen		= (1<<0),
-	MEMen		= (1<<1),
-	MASen		= (1<<2),
-	MemWrInv	= (1<<4),
-	PErrEn		= (1<<6),
-	SErrEn		= (1<<8),
+{					/* command register pcidev->pcr */
+	IOen		= 1<<0,
+	MEMen		= 1<<1,
+	MASen		= 1<<2,
+	MemWrInv	= 1<<4,
+	PErrEn		= 1<<6,
+	SErrEn		= 1<<8,
 };
 
 /*
@@ -132,38 +132,38 @@ enum {
 };
 
 enum {					/* Ctrl */
-	GIOmd		= (1<<2),	/* BIO master disable */
-	Lrst		= (1<<3),	/* link reset */
-	Slu		= (1<<6),	/* Set Link Up */
-	SspeedMASK	= (3<<8),	/* Speed Selection */
+	GIOmd		= 1<<2,		/* BIO master disable */
+	Lrst		= 1<<3,		/* link reset */
+	Slu		= 1<<6,		/* Set Link Up */
+	SspeedMASK	= 3<<8,		/* Speed Selection */
 	SspeedSHIFT	= 8,
 	Sspeed10	= 0x00000000,	/* 10Mb/s */
 	Sspeed100	= 0x00000100,	/* 100Mb/s */
 	Sspeed1000	= 0x00000200,	/* 1000Mb/s */
-	Frcspd		= (1<<11),	/* Force Speed */
-	Frcdplx		= (1<<12),	/* Force Duplex */
+	Frcspd		= 1<<11,	/* Force Speed */
+	Frcdplx		= 1<<12,	/* Force Duplex */
 	SwdpinsloMASK	= 0x003C0000,	/* Software Defined Pins - lo nibble */
 	SwdpinsloSHIFT	= 18,
 	SwdpioloMASK	= 0x03C00000,	/* Software Defined Pins - I or O */
 	SwdpioloSHIFT	= 22,
-	Devrst		= (1<<26),	/* Device Reset */
-	Rfce		= (1<<27),	/* Receive Flow Control Enable */
-	Tfce		= (1<<28),	/* Transmit Flow Control Enable */
-	Vme		= (1<<30),	/* VLAN Mode Enable */
-	Phy_rst		= (1<<31),	/* Phy Reset */
+	Devrst		= 1<<26,	/* Device Reset */
+	Rfce		= 1<<27,	/* Receive Flow Control Enable */
+	Tfce		= 1<<28,	/* Transmit Flow Control Enable */
+	Vme		= 1<<30,	/* VLAN Mode Enable */
+	Phy_rst		= 1<<31,	/* Phy Reset */
 };
 
 enum {					/* Status */
-	Lu		= (1<<1),	/* Link Up */
-	Lanid		= (3<<2),	/* mask for Lan ID.
-	Txoff		= (1<<4),	/* Transmission Paused */
-	Tbimode		= (1<<5),	/* TBI Mode Indication */
+	Lu		= 1<<1,		/* Link Up */
+	Lanid		= 3<<2,		/* mask for Lan ID.
+	Txoff		= 1<<4,		/* Transmission Paused */
+	Tbimode		= 1<<5,		/* TBI Mode Indication */
 	SpeedMASK	= 0x000000C0,
 	Speed10		= 0x00000000,	/* 10Mb/s */
 	Speed100	= 0x00000040,	/* 100Mb/s */
 	Speed1000	= 0x00000080,	/* 1000Mb/s */
-	Phyra		= (1<<10),	/* PHY Reset Asserted */
-	GIOme		= (1<<19),	/* GIO Master Enable Status */
+	Phyra		= 1<<10,	/* PHY Reset Asserted */
+	GIOme		= 1<<19,	/* GIO Master Enable Status */
 };
 
 enum {					/* Ctrl and Status */
@@ -175,25 +175,25 @@ enum {					/* Ctrl and Status */
 };
 
 enum {					/* Eec */
-	Sk		= (1<<0),	/* Clock input to the EEPROM */
-	Cs		= (1<<1),	/* Chip Select */
-	Di		= (1<<2),	/* Data Input to the EEPROM */
-	Do		= (1<<3),	/* Data Output from the EEPROM */
-	Areq		= (1<<6),	/* EEPROM Access Request */
-	Agnt		= (1<<7),	/* EEPROM Access Grant */
+	Sk		= 1<<0,		/* Clock input to the EEPROM */
+	Cs		= 1<<1,		/* Chip Select */
+	Di		= 1<<2,		/* Data Input to the EEPROM */
+	Do		= 1<<3,		/* Data Output from the EEPROM */
+	Areq		= 1<<6,		/* EEPROM Access Request */
+	Agnt		= 1<<7,		/* EEPROM Access Grant */
 };
 
 enum {					/* Eerd */
-	ee_start	= (1<<0),	/* Start Read */
-	ee_done		= (1<<1),	/* Read done */
-	ee_addr		= (0xfff8<<2),	/* Read address [15:2] */
-	ee_data		= (0xffff<<16),	/* Read Data; Data returned from eeprom/nvm */
+	ee_start	= 1<<0,		/* Start Read */
+	ee_done		= 1<<1,		/* Read done */
+	ee_addr		= 0xfff8<<2,	/* Read address [15:2] */
+	ee_data		= 0xffff<<16,	/* Read Data; Data returned from eeprom/nvm */
 };
 
 enum {					/* Ctrlext */
-	Asdchk		= (1<<12),	/* ASD Check */
-	Eerst		= (1<<13),	/* EEPROM Reset */
-	Spdbyps		= (1<<15),	/* Speed Select Bypass */
+	Asdchk		= 1<<12,	/* ASD Check */
+	Eerst		= 1<<13,	/* EEPROM Reset */
+	Spdbyps		= 1<<15,	/* Speed Select Bypass */
 };
 
 enum {					/* EEPROM content offsets */
@@ -235,6 +235,7 @@ enum {					/* Icr, Ics, Ims, Imc */
 	Gpi1		= 0x00001000,
 	Gpi2		= 0x00002000,
 	Gpi3		= 0x00004000,
+	Ack		= 0x00020000,	/* receive ACK frame */
 };
 
 enum {					/* Txcw */
@@ -242,8 +243,8 @@ enum {					/* Txcw */
 	TxcwHd		= 0x00000040,	/* Half Duplex */
 	TxcwPauseMASK	= 0x00000180,	/* Pause */
 	TxcwPauseSHIFT	= 7,
-	TxcwPs		= (1<<TxcwPauseSHIFT),	/* Pause Supported */
-	TxcwAs		= (2<<TxcwPauseSHIFT),	/* Asymmetric FC desired */
+	TxcwPs		= 1<<TxcwPauseSHIFT,	/* Pause Supported */
+	TxcwAs		= 2<<TxcwPauseSHIFT,	/* Asymmetric FC desired */
 	TxcwRfiMASK	= 0x00003000,	/* Remote Fault Indication */
 	TxcwRfiSHIFT	= 12,
 	TxcwNpr		= 0x00008000,	/* Next Page Request */
@@ -287,6 +288,7 @@ enum {					/* Tctl */
 	Trst		= 0x00000001,	/* Transmitter Software Reset */
 	Ten		= 0x00000002,	/* Transmit Enable */
 	Psp		= 0x00000008,	/* Pad Short Packets */
+	Mulr		= 0x10000000,	/* Allow multiple concurrent requests */
 	CtMASK		= 0x00000FF0,	/* Collision Threshold */
 	CtSHIFT		= 4,
 	ColdMASK	= 0x003FF000,	/* Collision Distance */
@@ -380,14 +382,30 @@ enum {
 	Ntdesc		= 128,		/* multiple of 8 */
 };
 
+enum{
+	i82563,
+	i82571,
+	i82573,
+};
+
+static char *tname[] = {
+	"i82563",
+	"i82571",
+	"i82573",
+};
+
+#define Type	tname[ctlr->type]
+
 typedef struct Ctlr Ctlr;
 struct Ctlr {
 	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
+	Pcidev	*pcidev;
+	Ctlr	*next;
 	int	active;
 	int	cls;
 	ushort	eeprom[0x40];
+	uchar	ra[Eaddrlen];		/* receive address */
+	int	type;
 
 	int*	nic;
 	Lock	imlock;
@@ -396,17 +414,14 @@ struct Ctlr {
 	Lock	slock;
 	uint	statistics[Nstatistics];
 
-	uchar	ra[Eaddrlen];		/* receive address */
-	ulong	mta[128];		/* multicast table array */
-
-	Rdesc*	rdba;			/* receive descriptor base address */
-	Block**	rb;			/* receive buffers */
+	Rdesc	*rdba;			/* receive descriptor base address */
+	Block	**rb;			/* receive buffers */
 	int	rdh;			/* receive descriptor head */
 	int	rdt;			/* receive descriptor tail */
 
-	Tdesc*	tdba;			/* transmit descriptor base address */
+	Tdesc	*tdba;			/* transmit descriptor base address */
 	Lock	tdlock;
-	Block**	tb;			/* transmit buffers */
+	Block	**tb;			/* transmit buffers */
 	int	tdh;			/* transmit descriptor head */
 	int	tdt;			/* transmit descriptor tail */
 
@@ -415,12 +430,12 @@ struct Ctlr {
 	int	fcrth;
 
 	/* bootstrap goo */
-	Block*	bqhead;	/* transmission queue */
-	Block*	bqtail;
+	Block	*bqhead;		/* transmission queue */
+	Block	*bqtail;
 };
 
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
+static Ctlr	*ctlrhead;
+static Ctlr	*ctlrtail;
 
 #define csr32r(c, r)	(*((c)->nic+((r)/4)))
 #define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v))
@@ -452,7 +467,7 @@ i82563attach(Ether* edev)
 static void
 txstart(Ether *edev)
 {
-	int tdh, tdt, len, olen;
+	int tdh, tdt;
 	Ctlr *ctlr = edev->ctlr;
 	Block *bp;
 	Tdesc *tdesc;
@@ -463,35 +478,17 @@ txstart(Ether *edev)
 	tdh = PREV(ctlr->tdh, Ntdesc);
 	for(tdt = ctlr->tdt; tdt != tdh; tdt = NEXT(tdt, Ntdesc)){
 		/* pull off the head of the transmission queue */
-		if((bp = ctlr->bqhead) == nil)		/* was qget(edev->oq) */
+		if((bp = ctlr->bqhead) == nil)	/* was qget(edev->oq) */
 			break;
 		ctlr->bqhead = bp->next;
 		if (ctlr->bqtail == bp)
 			ctlr->bqtail = nil;
-		len = olen = BLEN(bp);
-
-		/*
-		 * if packet is too short, make it longer rather than relying
-		 * on ethernet interface to pad it and complain so the caller
-		 * will get fixed.  I don't think Psp is working right, or it's
-		 * getting cleared.
-		 */
-		if (len < ETHERMINTU) {
-			if (bp->rp + ETHERMINTU <= bp->lim)
-				bp->wp = bp->rp + ETHERMINTU;
-			else
-				bp->wp = bp->lim;
-			len = BLEN(bp);
-			print("txstart: extended short pkt %d -> %d bytes\n",
-				olen, len);
-		}
 
 		/* set up a descriptor for it */
 		tdesc = &ctlr->tdba[tdt];
 		tdesc->addr[0] = PCIWADDR(bp->rp);
 		tdesc->addr[1] = 0;
-		tdesc->control = /* Ide| */ Rs|Dext|Ifcs|Teop|DtypeDD|len;
-		tdesc->status = 0;
+		tdesc->control = /* Ide | */ Rs | Ifcs | Teop | BLEN(bp);
 
 		ctlr->tb[tdt] = bp;
 	}
@@ -536,11 +533,11 @@ i82563transmit(Ether* edev)
 		tdesc = &ctlr->tdba[tdh];
 		if(!(tdesc->status & Tdd))
 			break;
-		tdesc->status = 0;
 		if(ctlr->tb[tdh] != nil){
 			freeb(ctlr->tb[tdh]);
 			ctlr->tb[tdh] = nil;
 		}
+		tdesc->status = 0;
 		tdh = NEXT(tdh, Ntdesc);
 	}
 	ctlr->tdh = tdh;
@@ -548,6 +545,8 @@ i82563transmit(Ether* edev)
 	/* copy packets from the software RingBuf to the transmission q */
 	while((tb = &edev->tb[edev->ti])->owner == Interface){
 		bp = fromringbuf(edev);
+//		print("#l%d: tx %d %E %E\n", edev->ctlrno, edev->ti, bp->rp,
+//			bp->rp+6);
 
 		if(ctlr->bqhead)
 			ctlr->bqtail->next = bp;
@@ -599,19 +598,22 @@ toringbuf(Ether *ether, Block *bp)
 		rb->len = BLEN(bp);
 		memmove(rb->pkt, bp->rp, rb->len);
 		rb->owner = Host;
+//		print("#l%d: toringbuf: %d %p\n", ether->ctlrno, ether->ri,
+//			ether);
 		ether->ri = NEXT(ether->ri, ether->nrb);
-	}
-	/* else no one is expecting packets from the network */
+	}else
+		print("#l%d: toringbuf: dropping packets @ %d\n",
+			ether->ctlrno, ether->ri);
 }
 
 static void
 i82563interrupt(Ureg*, void* arg)
 {
+	int icr, im, rdh, txdw = 0;
 	Block *bp;
 	Ctlr *ctlr;
 	Ether *edev;
 	Rdesc *rdesc;
-	int icr, im, rdh, txdw = 0;
 
 	edev = arg;
 	ctlr = edev->ctlr;
@@ -622,6 +624,7 @@ i82563interrupt(Ureg*, void* arg)
 
 	for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){
 		if(icr & (Rxseq|Lsc)){
+			/* should be more here */
 		}
 
 		rdh = ctlr->rdh;
@@ -631,13 +634,17 @@ i82563interrupt(Ureg*, void* arg)
 				break;
 			if ((rdesc->status & Reop) && rdesc->errors == 0) {
 				bp = ctlr->rb[rdh];
+				if(0 && memcmp(bp->rp, broadcast, 6) != 0)
+					print("#l%d: rx %d %E %E %d\n",
+						edev->ctlrno, rdh, bp->rp,
+						bp->rp+6, rdesc->length);
 				ctlr->rb[rdh] = nil;
 				bp->wp += rdesc->length;
 				toringbuf(edev, bp);
 				freeb(bp);
-			} else if ((rdesc->status & Reop) && rdesc->errors)
-				print("i82563: input packet error 0x%ux\n",
-					rdesc->errors);
+			} else if (rdesc->status & Reop && rdesc->errors)
+				print("%s: input packet error 0x%ux\n",
+					Type, rdesc->errors);
 			rdesc->status = 0;
 			rdh = NEXT(rdh, Nrdesc);
 		}
@@ -663,9 +670,9 @@ i82563init(Ether* edev)
 	Ctlr *ctlr;
 
 	ctlr = edev->ctlr;
-	csr = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
+	csr = edev->ea[3]<<24 | edev->ea[2]<<16 | edev->ea[1]<<8 | edev->ea[0];
 	csr32w(ctlr, Ral, csr);
-	csr = 0x80000000|(edev->ea[5]<<8)|edev->ea[4];
+	csr = 0x80000000 | edev->ea[5]<<8 | edev->ea[4];
 	csr32w(ctlr, Rah, csr);
 	for (i = 1; i < 16; i++) {
 		csr32w(ctlr, Ral+i*8, 0);
@@ -674,7 +681,7 @@ i82563init(Ether* edev)
 	for(i = 0; i < 128; i++)
 		csr32w(ctlr, Mta+i*4, 0);
 	csr32w(ctlr, Rctl, 0);
-	ctlr->rdba = xspanalloc(Nrdesc*sizeof(Rdesc), 128 /* was 16 */, 0);
+	ctlr->rdba = xspanalloc(Nrdesc*sizeof(Rdesc), 256, 0);
 	csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
 	csr32w(ctlr, Rdbah, 0);
 	csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
@@ -685,14 +692,17 @@ i82563init(Ether* edev)
 	ctlr->rb = malloc(sizeof(Block*)*Nrdesc);
 	i82563replenish(ctlr);
 	csr32w(ctlr, Rdtr, 0);
-	csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam);
-	i82563im(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
+	csr32w(ctlr, Rctl, Dpf | Bsize2048 | Bam | RdtmsHALF);
+	i82563im(ctlr, Rxt0 | Rxo | Rxdmt0 | Rxseq | Ack);
 
-	csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(0x3f<<ColdSHIFT));	/* Fd */
-	csr32w(ctlr, Tipg, (7<<20)|(8<<10)|9);
+	csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 0x3f<<ColdSHIFT | Mulr);
+	csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);
 	csr32w(ctlr, Tidv, 1);
-	ctlr->tdba = xspanalloc(Ntdesc*sizeof(Tdesc), 128 /* was 16 */, 0);
+
+	ctlr->tdba = xspanalloc(Ntdesc*sizeof(Tdesc), 256, 0);
+	memset(ctlr->tdba, 0, Ntdesc*sizeof(Tdesc));
 	csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
+
 	csr32w(ctlr, Tdbah, 0);
 	csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
 	ctlr->tdh = 0;
@@ -701,8 +711,9 @@ i82563init(Ether* edev)
 	csr32w(ctlr, Tdt, ctlr->tdt);
 	ctlr->tb = malloc(sizeof(Block*)*Ntdesc);
 
-	r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
-	csr32w(ctlr, Txdctl, r);
+//	r = 4<<WthreshSHIFT | 4<<HthreshSHIFT | 8<<PthreshSHIFT;
+//	csr32w(ctlr, Txdctl, r);
+	csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE<<PcssSHIFT);
 	r = csr32r(ctlr, Tctl);
 	r |= Ten;
 	csr32w(ctlr, Tctl, r);
@@ -737,18 +748,26 @@ eeload(Ctlr* ctlr)
 static void
 detach(Ctlr *ctlr)
 {
+	int r;
+
 	csr32w(ctlr, Imc, ~0);
 	csr32w(ctlr, Rctl, 0);
 	csr32w(ctlr, Tctl, 0);
 
 	delay(10);
 
-	csr32w(ctlr, Ctrl, Devrst);
+	r = csr32r(ctlr, Ctrl);
+	csr32w(ctlr, Ctrl, Devrst | r);
 	/* apparently needed on multi-GHz processors to avoid infinite loops */
 	delay(1);
 	while(csr32r(ctlr, Ctrl) & Devrst)
 		;
 
+	if(1 || ctlr->type != i82563){
+		r = csr32r(ctlr, Ctrl);
+		csr32w(ctlr, Ctrl, Slu | r);
+	}
+
 	csr32w(ctlr, Ctrlext, Eerst | csr32r(ctlr, Ctrlext));
 	delay(1);
 	while(csr32r(ctlr, Ctrlext) & Eerst)
@@ -781,30 +800,32 @@ i82563reset(Ctlr* ctlr)
 
 	r = eeload(ctlr);
 	if (r != 0 && r != 0xBABA){
-		print("i82563: bad EEPROM checksum - 0x%4.4uX\n", r);
+		print("%s: bad EEPROM checksum - 0x%4.4ux\n", Type, r);
 		return -1;
 	}
 
 	for(i = Ea; i < Eaddrlen/2; i++){
-		ctlr->ra[2*i] = ctlr->eeprom[i];
+		ctlr->ra[2*i]   = ctlr->eeprom[i];
 		ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
 	}
-	r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
+	r = csr32r(ctlr, Status)>>2;
+	ctlr->ra[5] += r & 3;		/* ea ctlr[1] = ea ctlr[0]+1 */
+
+	r = ctlr->ra[3]<<24 | ctlr->ra[2]<<16 | ctlr->ra[1]<<8 | ctlr->ra[0];
 	csr32w(ctlr, Ral, r);
-	r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
+	r = 0x80000000 | ctlr->ra[5]<<8 | ctlr->ra[4];
 	csr32w(ctlr, Rah, r);
 	for(i = 1; i < 16; i++){
 		csr32w(ctlr, Ral+i*8, 0);
 		csr32w(ctlr, Rah+i*8, 0);
 	}
 
-	memset(ctlr->mta, 0, sizeof(ctlr->mta));
 	for(i = 0; i < 128; i++)
 		csr32w(ctlr, Mta+i*4, 0);
 
 	csr32w(ctlr, Fcal, 0x00C28001);
 	csr32w(ctlr, Fcah, 0x00000100);
-	csr32w(ctlr, Fct, 0x00008808);
+	csr32w(ctlr, Fct,  0x00008808);
 	csr32w(ctlr, Fcttv, 0x00000100);
 
 	csr32w(ctlr, Fcrtl, ctlr->fcrtl);
@@ -812,16 +833,17 @@ i82563reset(Ctlr* ctlr)
 
 	ilock(&ctlr->imlock);
 	csr32w(ctlr, Imc, ~0);
-	ctlr->im = Lsc;
+	ctlr->im = 0;		/* was = Lsc, which hangs some controllers */
 	csr32w(ctlr, Ims, ctlr->im);
 	iunlock(&ctlr->imlock);
+
 	return 0;
 }
 
 static void
 i82563pci(void)
 {
-	int port, cls;
+	int port, type, cls;
 	Pcidev *p;
 	Ctlr *ctlr;
 	static int first = 1;
@@ -832,17 +854,22 @@ i82563pci(void)
 		return;
 
 	p = nil;
-	while(p = pcimatch(p, 0, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-		if (p->did != 0x1096)
-			continue;
-		if (p->vid != 0x8086)
+	while(p = pcimatch(p, 0x8086, 0)){
+		switch(p->did){
+		case 0x1096:
+			type = i82563;
+			break;
+		case 0x108c:
+		case 0x109a:
+			type = i82573;
+			break;
+		default:
 			continue;
+		}
 
 		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
 		if(port == 0){
-			print("i82563: can't map %d @ 0x%8.8luX\n",
+			print("%s: can't map %d @ 0x%8.8lux\n", tname[type],
 				p->mem[0].size, p->mem[0].bar);
 			continue;
 		}
@@ -856,14 +883,14 @@ i82563pci(void)
 		cls = pcicfgr8(p, PciCLS);
 		switch(cls){
 		default:
-			print("i82563: unexpected CLS - %d bytes\n",
-				cls*sizeof(long));
+			print("%s: unexpected CLS - %d bytes\n",
+				tname[type], cls*sizeof(long));
 			break;
 		case 0x00:
 		case 0xFF:
 			/* alphapc 164lx returns 0 */
-			print("i82563: unusable PciCLS: %d, using %d longs\n",
-				cls, CACHELINESZ/sizeof(long));
+			print("%s: unusable PciCLS: %d, using %d longs\n",
+				tname[type], cls, CACHELINESZ/sizeof(long));
 			cls = CACHELINESZ/sizeof(long);
 			pcicfgw8(p, PciCLS, cls);
 			break;
@@ -876,6 +903,7 @@ i82563pci(void)
 		ctlr->port = port;
 		ctlr->pcidev = p;
 		ctlr->cls = cls*4;
+		ctlr->type = type;
 		ctlr->nic = KADDR(ctlr->port);
 		if(i82563reset(ctlr)){
 			free(ctlr);
@@ -891,12 +919,12 @@ i82563pci(void)
 	}
 }
 
+static uchar nilea[Eaddrlen];
+
 int
 i82563pnp(Ether* edev)
 {
-	int i;
 	Ctlr *ctlr;
-	uchar ea[Eaddrlen];
 
 	if(ctlrhead == nil)
 		i82563pci();
@@ -922,18 +950,8 @@ i82563pnp(Ether* edev)
 	edev->tbdf = ctlr->pcidev->tbdf;
 //	edev->mbps = 1000;
 
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the EEPROM and set in ether->ea prior to
-	 * loading the station address in the hardware.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, edev->ea, Eaddrlen) == 0){
-		for(i = 0; i < Eaddrlen/2; i++){
-			edev->ea[2*i] = ctlr->eeprom[i];
-			edev->ea[2*i+1] = ctlr->eeprom[i]>>8;
-		}
-	}
+	if(memcmp(edev->ea, nilea, Eaddrlen) == 0)
+		memmove(edev->ea, ctlr->ra, Eaddrlen);
 	i82563init(edev);
 
 	/*
@@ -944,5 +962,16 @@ i82563pnp(Ether* edev)
 	edev->interrupt = i82563interrupt;
 	edev->detach = i82563detach;
 
+	/*
+	 * with the current structure, there is no right place for this.
+	 * ideally, we recognize the interface, note it's down and move on.
+	 * currently either we can skip the interface or note it is down,
+	 * but not both.
+	 */
+	if((csr32r(ctlr, Status)&Lu) == 0){
+		print("ether#%d: 82563 (%s): link down\n", edev->ctlrno, Type);
+		return -1;
+	}
+
 	return 0;
 }

+ 38 - 16
sys/src/boot/pc/etherigbe.c

@@ -30,6 +30,9 @@
 #include "etherif.h"
 #include "ethermii.h"
 
+enum {
+	Debug = 0,		/* mostly for X60 debugging */
+};
 enum {
 	i82542     = (0x1000<<16)|0x8086,
 	i82543gc   = (0x1004<<16)|0x8086,
@@ -42,6 +45,7 @@ enum {
 	i82541gi   = (0x1076<<16)|0x8086,
 	i82546gb   = (0x1079<<16)|0x8086,
 	i82541pi   = (0x107c<<16)|0x8086,
+	i82573pl   = (0x109a<<16)|0x8086,
 };
 
 /* compatibility with cpu kernels */
@@ -726,7 +730,7 @@ igbeinterrupt(Ureg*, void* arg)
 		 */
 		if(icr & (Rxseq|Lsc)){
 			/*
-			 * More here...
+			 * should be more here...
 			 */
 		}
 
@@ -851,6 +855,7 @@ igbeinit(Ether* edev)
 	case i82546gb:
 	case i82546eb:
 	case i82547gi:
+	case i82573pl:
 		csr32w(ctlr, Radv, 64);
 		break;
 	}
@@ -893,6 +898,7 @@ igbeinit(Ether* edev)
 	case i82546gb:
 	case i82546eb:
 	case i82547gi:
+	case i82573pl:
 		r = 8;
 		break;
 	}
@@ -931,6 +937,7 @@ igbeinit(Ether* edev)
 	case i82546gb:
 	case i82546eb:
 	case i82541gi:
+	case i82573pl:
 		r = csr32r(ctlr, Txdctl);
 		r &= ~WthreshMASK;
 		r |= Gran|(4<<WthreshSHIFT);
@@ -1162,6 +1169,7 @@ igbemii(Ctlr* ctlr)
 	case i82541pi:
 	case i82546gb:
 	case i82546eb:
+	case i82573pl:
 		ctrl &= ~(Frcdplx|Frcspd);
 		csr32w(ctlr, Ctrl, ctrl);
 		ctlr->mii->mir = igbemiimir;
@@ -1180,7 +1188,10 @@ igbemii(Ctlr* ctlr)
 		ctlr->mii = nil;
 		return -1;
 	}
-	print("oui %X phyno %d\n", phy->oui, phy->phyno);
+	if (Debug)
+		print("oui %X phyno %d\n", phy->oui, phy->phyno);
+	else
+		USED(phy);
 
 	/*
 	 * 8254X-specific PHY registers not in 802.3:
@@ -1326,6 +1337,7 @@ at93c46r(Ctlr* ctlr)
 	case i82547gi:
 	case i82546gb:
 	case i82546eb:
+//	case i82573pl:
 		areq = 1;
 		csr32w(ctlr, Eecd, eecd|Areq);
 		for(i = 0; i < 1000; i++){
@@ -1356,13 +1368,14 @@ at93c46r(Ctlr* ctlr)
 		at93c46io(ctlr, "sic", 0);
 		ctlr->eeprom[addr] = data;
 		sum += data;
-
-		if(addr && ((addr & 0x07) == 0))
-			print("\n");
-		print(" %4.4ux", data);
+		if (Debug) {
+			if(addr && ((addr & 0x07) == 0))
+				print("\n");
+			print(" %4.4ux", data);
+		}
 	}
-	print("\n");
-
+	if (Debug)
+		print("\n");
 release:
 	if(areq)
 		csr32w(ctlr, Eecd, eecd & ~Areq);
@@ -1406,6 +1419,7 @@ detach(Ctlr *ctlr)
 	case i82547gi:
 	case i82546gb:
 	case i82546eb:
+	case i82573pl:
 		r = csr32r(ctlr, Manc);
 		r &= ~Arpen;
 		csr32w(ctlr, Manc, r);
@@ -1454,14 +1468,19 @@ igbereset(Ctlr* ctlr)
 	 * There are 16 addresses. The first should be the MAC address.
 	 * The others are cleared and not marked valid (MS bit of Rah).
 	 */
-	if ((ctlr->id == i82546gb || ctlr->id == i82546eb) && BUSFNO(ctlr->pcidev->tbdf) == 1)
-		ctlr->eeprom[Ea+2] += 0x100;	// second interface
+	if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
+	    BUSFNO(ctlr->pcidev->tbdf) == 1)
+		ctlr->eeprom[Ea+2] += 0x100;		/* second interface */
 	for(i = Ea; i < Eaddrlen/2; i++){
-if(i == Ea && ctlr->id == i82541gi && ctlr->eeprom[i] == 0xFFFF)
-    ctlr->eeprom[i] = 0xD000;
-		ctlr->ra[2*i] = ctlr->eeprom[i];
+		if(i == Ea && ctlr->id == i82541gi && ctlr->eeprom[i] == 0xFFFF)
+			ctlr->eeprom[i] = 0xD000;
+		ctlr->ra[2*i]   = ctlr->eeprom[i];
 		ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
 	}
+	/* set mac address of second port */
+	r = csr32r(ctlr, Status)>>2;
+	ctlr->ra[5] += r & 3;		/* ea ctlr[1] = ea ctlr[0]+1 */
+
 	r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
 	csr32w(ctlr, Ral, r);
 	r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
@@ -1547,7 +1566,7 @@ if(i == Ea && ctlr->id == i82541gi && ctlr->eeprom[i] == 0xFFFF)
 
 	ilock(&ctlr->imlock);
 	csr32w(ctlr, Imc, ~0);
-	ctlr->im = Lsc;
+	ctlr->im = 0;		/* was = Lsc, which hangs some controllers */
 	csr32w(ctlr, Ims, ctlr->im);
 	iunlock(&ctlr->imlock);
 
@@ -1594,6 +1613,7 @@ igbepci(void)
 		case i82541pi:
 		case i82546gb:
 		case i82546eb:
+		case i82573pl:
 			break;
 		}
 
@@ -1641,12 +1661,14 @@ igbepci(void)
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->cls = cls*4;
 		ctlr->nic = KADDR(ctlr->port);
-print("status0 %8.8uX\n", csr32r(ctlr, Status));
+		if (Debug)
+			print("status0 %8.8uX\n", csr32r(ctlr, Status));
 		if(igbereset(ctlr)){
 			free(ctlr);
 			continue;
 		}
-print("status1 %8.8uX\n", csr32r(ctlr, Status));
+		if (Debug)
+			print("status1 %8.8uX\n", csr32r(ctlr, Status));
 		pcisetbme(p);
 
 		if(ctlrhead != nil)

+ 229 - 179
sys/src/cmd/upas/smtp/smtpd.c

@@ -40,12 +40,13 @@ char	*tlscert;
 List	senders;
 List	rcvers;
 
-char pipbuf[ERRMAX];
+char	pipbuf[ERRMAX];
 char	*piperror;
+
+String*	mailerpath(char*);
 int	pipemsg(int*);
-String*	startcmd(void);
 int	rejectcheck(void);
-String*	mailerpath(char*);
+String*	startcmd(void);
 
 static int
 catchalarm(void *a, char *msg)
@@ -57,7 +58,8 @@ catchalarm(void *a, char *msg)
 	/* log alarms but continue */
 	if(strstr(msg, "alarm")){
 		if(senders.first && rcvers.first)
-			syslog(0, "smtpd", "note: %s->%s: %s", s_to_c(senders.first->p),
+			syslog(0, "smtpd", "note: %s->%s: %s",
+				s_to_c(senders.first->p),
 				s_to_c(rcvers.first->p), msg);
 		else
 			syslog(0, "smtpd", "note: %s", msg);
@@ -71,7 +73,7 @@ catchalarm(void *a, char *msg)
 	return rv;
 }
 
-	/* override string error functions to do something reasonable */
+/* override string error functions to do something reasonable */
 void
 s_error(char *f, char *status)
 {
@@ -80,31 +82,42 @@ s_error(char *f, char *status)
 	errbuf[0] = 0;
 	rerrstr(errbuf, sizeof(errbuf));
 	if(f && *f)
-		reply("452 out of memory %s: %s\r\n", f, errbuf);
+		reply("452 4.3.0 out of memory %s: %s\r\n", f, errbuf);
 	else
-		reply("452 out of memory %s\r\n", errbuf);
+		reply("452 4.3.0 out of memory %s\r\n", errbuf);
 	syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys);
 	exits(status);
 }
 
+static void
+usage(void)
+{
+	fprint(2,
+	  "usage: smtpd [-adDfghprs] [-c cert] [-k ip] [-m mailer] [-n net]\n");
+	exits("usage");
+}
+
 void
 main(int argc, char **argv)
 {
-	char *p, buf[1024];
 	char *netdir;
+	char buf[1024];
 
 	netdir = nil;
 	quotefmtinstall();
 	ARGBEGIN{
+	case 'a':
+		authenticate = 1;
+		break;
+	case 'c':
+		tlscert = EARGF(usage());
+		break;
 	case 'D':
 		Dflag++;
 		break;
 	case 'd':
 		debug++;
 		break;
-	case 'n':				/* log peer ip address */
-		netdir = ARGF();
-		break;
 	case 'f':				/* disallow relaying */
 		fflag = 1;
 		break;
@@ -112,17 +125,19 @@ main(int argc, char **argv)
 		gflag = 1;
 		break;
 	case 'h':				/* default domain name */
-		dom = ARGF();
+		dom = EARGF(usage());
 		break;
 	case 'k':				/* prohibited ip address */
-		p = ARGF();
-		if (p)
-			addbadguy(p);
+		addbadguy(EARGF(usage()));
 		break;
 	case 'm':				/* set mail command */
-		p = ARGF();
-		if(p)
-			mailer = mailerpath(p);
+		mailer = mailerpath(EARGF(usage()));
+		break;
+	case 'n':				/* log peer ip address */
+		netdir = EARGF(usage());
+		break;
+	case 'p':
+		passwordinclear = 1;
 		break;
 	case 'r':
 		rflag = 1;			/* verify sender's domain */
@@ -130,22 +145,13 @@ main(int argc, char **argv)
 	case 's':				/* save blocked messages */
 		sflag = 1;
 		break;
-	case 'a':
-		authenticate = 1;
-		break;
-	case 'p':
-		passwordinclear = 1;
-		break;
-	case 'c':
-		tlscert = ARGF();
-		break;
 	case 't':
-		fprint(2, "%s: the -t option is no longer supported, see -c\n", argv0);
+		fprint(2, "%s: the -t option is no longer supported, see -c\n",
+			argv0);
 		tlscert = "/sys/lib/ssl/smtpd-cert.pem";
 		break;
 	default:
-		fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n");
-		exits("usage");
+		usage();
 	}ARGEND;
 
 	nci = getnetconninfo(netdir, 0);
@@ -175,7 +181,8 @@ main(int argc, char **argv)
 		dom = me;
 	sayhi();
 	parseinit();
-		/* allow 45 minutes to parse the header */
+
+	/* allow 45 minutes to parse the header */
 	atnotify(catchalarm, 1);
 	alarm(45*60*1000);
 	zzparse();
@@ -185,8 +192,7 @@ main(int argc, char **argv)
 void
 listfree(List *l)
 {
-	Link *lp;
-	Link *next;
+	Link *lp, *next;
 
 	for(lp = l->first; lp; lp = next){
 		next = lp->next;
@@ -201,7 +207,7 @@ listadd(List *l, String *path)
 {
 	Link *lp;
 
-	lp = (Link *)malloc(sizeof(Link));
+	lp = (Link *)malloc(sizeof *lp);
 	lp->p = path;
 	lp->next = 0;
 
@@ -213,17 +219,19 @@ listadd(List *l, String *path)
 }
 
 #define	SIZE	4096
+
 int
 reply(char *fmt, ...)
 {
+	int n;
 	char buf[SIZE], *out;
 	va_list arg;
-	int n;
 
 	va_start(arg, fmt);
 	out = vseprint(buf, buf+SIZE, fmt, arg);
 	va_end(arg);
-	n = (long)(out-buf);
+
+	n = (long)(out - buf);
 	if(debug) {
 		seek(2, 0, 2);
 		write(2, buf, n);
@@ -243,26 +251,29 @@ reset(void)
 		logged = 0;
 		filterstate = ACCEPT;
 	}
-	reply("250 ok\r\n");
+	reply("250 2.0.0 ok\r\n");
 }
 
 void
 sayhi(void)
 {
-	reply("220 %s SMTP\r\n", dom);
+	reply("220 %s ESMTP\r\n", dom);
 }
 
 void
 hello(String *himp, int extended)
 {
 	char **mynames;
+	char *ldot, *rdot;
 
 	him = s_to_c(himp);
-	syslog(0, "smtpd", "%s from %s as %s", extended ? "ehlo" : "helo", nci->rsys, him);
+	syslog(0, "smtpd", "%s from %s as %s", extended? "ehlo": "helo",
+		nci->rsys, him);
 	if(rejectcheck())
 		return;
 
-	if(strchr(him, '.') && nci && !trusted && fflag && strcmp(nci->rsys, nci->lsys) != 0){
+	if (strchr(him, '.') && nci && !trusted && fflag &&
+	    strcmp(nci->rsys, nci->lsys) != 0){
 		/*
 		 * We don't care if he lies about who he is, but it is
 		 * not okay to pretend to be us.  Many viruses do this,
@@ -270,29 +281,60 @@ hello(String *himp, int extended)
 		 */
 		if(strcmp(him, dom) == 0)
 			goto Liarliar;
-		for(mynames=sysnames_read(); mynames && *mynames; mynames++){
+		for(mynames = sysnames_read(); mynames && *mynames; mynames++){
 			if(cistrcmp(*mynames, him) == 0){
-			Liarliar:
-				syslog(0, "smtpd", "Hung up on %s; claimed to be %s",
+Liarliar:
+				syslog(0, "smtpd",
+					"Hung up on %s; claimed to be %s",
 					nci->rsys, him);
-				reply("554 Liar!\r\n");
+				reply("554 5.7.0 Liar!\r\n");
 				exits("client pretended to be us");
 				return;
 			}
 		}
 	}
+
 	/*
-	 * it is never acceptable to claim to be "localhost",
-	 * "localhost.localdomain" or "localhost.example.com"; only spammers
-	 * do this.  it is also unacceptable to claim any string that doesn't
-	 * look like a domain name (e.g., has at least one dot in it), but
+	 * it is unacceptable to claim any string that doesn't look like
+	 * a domain name (e.g., has at least one dot in it), but
 	 * Microsoft mail client software gets this wrong, so let trusted
-	 * (local) clients get it wrong.
+	 * (local) clients omit the dot.
 	 */
-	if (!trusted && strchr(him, '.') == nil ||
-	    strcmp(him, "localhost.localdomain") == 0 ||
-	    strcmp(him, "localhost.example.com") == 0)
+	rdot = strrchr(him, '.');
+	if (rdot && rdot[1] == '\0') {
+		*rdot = '\0';			/* clobber trailing dot */
+		rdot = strrchr(him, '.');	/* try again */
+	}
+	if (!trusted && rdot == nil)
 		goto Liarliar;
+	/*
+	 * Reject obviously bogus domains and those reserved by RFC 2606.
+	 */
+	if (rdot == nil)
+		rdot = him;
+	else
+		rdot++;
+	if (cistrcmp(rdot, "localdomain") == 0 ||
+	    cistrcmp(rdot, "localhost") == 0 ||
+	    cistrcmp(rdot, "example") == 0 ||
+	    cistrcmp(rdot, "invalid") == 0 ||
+	    cistrcmp(rdot, "test") == 0)
+		goto Liarliar;			/* bad top-level domain */
+	/* check second-level RFC 2606 domains: example\.(com|net|org) */
+	if (rdot != him)
+		*--rdot = '\0';
+	ldot = strrchr(him, '.');
+	if (rdot != him)
+		*rdot = '.';
+	if (ldot == nil)
+		ldot = him;
+	else
+		ldot++;
+	if (cistrcmp(ldot, "example.com") == 0 ||
+	    cistrcmp(ldot, "example.net") == 0 ||
+	    cistrcmp(ldot, "example.org") == 0)
+		goto Liarliar;
+
 	/*
 	 * similarly, if the claimed domain is not an address-literal,
 	 * require at least one letter, which there will be in
@@ -316,9 +358,10 @@ hello(String *himp, int extended)
 		sleep(15*1000);
 	reply("250%c%s you are %s\r\n", extended ? '-' : ' ', dom, him);
 	if (extended) {
+		reply("250-ENHANCEDSTATUSCODES\r\n");	/* RFCs 2034 and 3463 */
 		if(tlscert != nil)
 			reply("250-STARTTLS\r\n");
-		if (passwordinclear)		
+		if (passwordinclear)
 			reply("250 AUTH CRAM-MD5 PLAIN LOGIN\r\n");
 		else
 			reply("250 AUTH CRAM-MD5\r\n");
@@ -335,7 +378,7 @@ sender(String *path)
 		return;
 	if (authenticate && !authenticated) {
 		rejectcount++;
-		reply("530 Authentication required\r\n");
+		reply("530 5.7.0 Authentication required\r\n");
 		return;
 	}
 	if(him == 0 || *him == 0){
@@ -356,19 +399,22 @@ sender(String *path)
 	}
 	if(shellchars(s_to_c(path))){
 		rejectcount++;
-		reply("503 Bad character in sender address %s.\r\n", s_to_c(path));
+		reply("501 5.1.3 Bad character in sender address %s.\r\n",
+			s_to_c(path));
 		return;
 	}
 
 	/*
 	 * if the last sender address resulted in a rejection because the sending
-	 * domain didn't exist and this sender has the same domain, reject immediately.
+	 * domain didn't exist and this sender has the same domain, reject
+	 * immediately.
 	 */
 	if(lastsender){
 		if (strncmp(lastsender, s_to_c(path), strlen(lastsender)) == 0){
 			filterstate = REFUSED;
 			rejectcount++;
-			reply("554 Sender domain must exist: %s\r\n", s_to_c(path));
+			reply("554 5.1.8 Sender domain must exist: %s\r\n",
+				s_to_c(path));
 			return;
 		}
 		free(lastsender);	/* different sender domain */
@@ -382,7 +428,7 @@ sender(String *path)
 
 	logged = 0;
 	listadd(&senders, path);
-	reply("250 sender is %s\r\n", s_to_c(path));
+	reply("250 2.0.0 sender is %s\r\n", s_to_c(path));
 }
 
 enum { Rcpt, Domain, Ntoks };
@@ -521,53 +567,47 @@ receiver(String *path)
 		syslog(0, "smtpd",
 		 "Disallowed %s (%s/%s) to blocked, unknown or invalid name %s",
 			sender, him, nci->rsys, s_to_c(path));
-		reply("550 %s ... user unknown\r\n", s_to_c(path));
+		reply("550 5.1.1 %s ... user unknown\r\n", s_to_c(path));
 		return;
 	}
 	rcpt = s_to_c(path);
 	if (!senderok(rcpt)) {
 		rejectcount++;
 		syslog(0, "smtpd", "Disallowed sending IP of %s (%s/%s) to %s",
-				sender, him, nci->rsys, rcpt);
-		reply("550 %s ... sending system not allowed\r\n", rcpt);
+			sender, him, nci->rsys, rcpt);
+		reply("550 5.7.1 %s ... sending system not allowed\r\n", rcpt);
 		return;
 	}
 
 	logged = 0;
-		/* forwarding() can modify 'path' on loopback request */
-	if(filterstate == ACCEPT && (fflag && !authenticated) && forwarding(path)) {
+
+	/* forwarding() can modify 'path' on loopback request */
+	if(filterstate == ACCEPT && fflag && !authenticated && forwarding(path)) {
 		syslog(0, "smtpd", "Bad Forward %s (%s/%s) (%s)",
 			s_to_c(senders.last->p), him, nci->rsys, s_to_c(path));
 		rejectcount++;
-		reply("550 we don't relay.  send to your-path@[] for loopback.\r\n");
+		reply("550 5.7.1 we don't relay.  send to your-path@[] for "
+			"loopback.\r\n");
 		return;
 	}
 	listadd(&rcvers, path);
-	reply("250 receiver is %s\r\n", s_to_c(path));
+	reply("250 2.0.0 receiver is %s\r\n", s_to_c(path));
 }
 
 void
 quit(void)
 {
-	reply("221 Successful termination\r\n");
+	reply("221 2.0.0 Successful termination\r\n");
 	close(0);
 	exits(0);
 }
 
-void
-turn(void)
-{
-	if(rejectcheck())
-		return;
-	reply("502 TURN unimplemented\r\n");
-}
-
 void
 noop(void)
 {
 	if(rejectcheck())
 		return;
-	reply("250 Stop wasting my time!\r\n");
+	reply("250 2.0.0 Nothing to see here. Move along ...\r\n");
 }
 
 void
@@ -577,7 +617,7 @@ help(String *cmd)
 		return;
 	if(cmd)
 		s_free(cmd);
-	reply("250 Read rfc821 and stop wasting my time\r\n");
+	reply("250 2.0.0 See http://www.ietf.org/rfc/rfc2821\r\n");
 }
 
 void
@@ -589,7 +629,7 @@ verify(String *path)
 	if(rejectcheck())
 		return;
 	if(shellchars(s_to_c(path))){
-		reply("503 Bad character in address %s.\r\n", s_to_c(path));
+		reply("503 5.1.3 Bad character in address %s.\r\n", s_to_c(path));
 		return;
 	}
 	av[0] = s_to_c(mailer);
@@ -599,22 +639,22 @@ verify(String *path)
 
 	pp = noshell_proc_start(av, (stream *)0, outstream(),  (stream *)0, 1, 0);
 	if (pp == 0) {
-		reply("450 We're busy right now, try later\r\n");
+		reply("450 4.3.2 We're busy right now, try later\r\n");
 		return;
 	}
 
 	p = Brdline(pp->std[1]->fp, '\n');
 	if(p == 0){
-		reply("550 String does not match anything.\r\n");
+		reply("550 5.1.0 String does not match anything.\r\n");
 	} else {
 		p[Blinelen(pp->std[1]->fp)-1] = 0;
 		if(strchr(p, ':'))
-			reply("550 String does not match anything.\r\n");
+			reply("550 5.1.0  String does not match anything.\r\n");
 		else{
 			q = strrchr(p, '!');
 			if(q)
 				p = q+1;
-			reply("250 %s <%s@%s>\r\n", s_to_c(path), p, dom);
+			reply("250 2.0.0 %s <%s@%s>\r\n", s_to_c(path), p, dom);
 		}
 	}
 	proc_wait(pp);
@@ -727,10 +767,10 @@ String*
 startcmd(void)
 {
 	int n;
-	Link *l;
+	char *filename;
 	char **av;
+	Link *l;
 	String *cmd;
-	char *filename;
 
 	/*
 	 *  ignore the filterstate if the all the receivers prefer it.
@@ -751,32 +791,37 @@ startcmd(void)
 	case DIALUP:
 		logmsg("Dialup");
 		rejectcount++;
-		reply("554 We don't accept mail from dial-up ports.\r\n");
+		reply("554 5.7.1 We don't accept mail from dial-up ports.\r\n");
 		/*
-		 * we could exit here, because we're never going to accept mail from this
-		 * ip address, but it's unclear that RFC821 allows that.  Instead we set
-		 * the hardreject flag and go stupid.
+		 * we could exit here, because we're never going to accept mail
+		 * from this ip address, but it's unclear that RFC821 allows
+		 * that.  Instead we set the hardreject flag and go stupid.
 		 */
 		hardreject = 1;
 		return 0;
 	case DENIED:
 		logmsg("Denied");
 		rejectcount++;
-		reply("554-We don't accept mail from %s.\r\n", s_to_c(senders.last->p));
-		reply("554 Contact postmaster@%s for more information.\r\n", dom);
+		reply("554-5.7.1 We don't accept mail from %s.\r\n",
+			s_to_c(senders.last->p));
+		reply("554 5.7.1 Contact postmaster@%s for more information.\r\n",
+			dom);
 		return 0;
 	case REFUSED:
 		logmsg("Refused");
 		rejectcount++;
-		reply("554 Sender domain must exist: %s\r\n", s_to_c(senders.last->p));
+		reply("554 5.7.1 Sender domain must exist: %s\r\n",
+			s_to_c(senders.last->p));
 		return 0;
 	default:
 	case NONE:
 		logmsg("Confused");
 		rejectcount++;
-		reply("554-We have had an internal mailer error classifying your message.\r\n");
-		reply("554-Filterstate is %d\r\n", filterstate);
-		reply("554 Contact postmaster@%s for more information.\r\n", dom);
+		reply("554-5.7.0 We have had an internal mailer error "
+			"classifying your message.\r\n");
+		reply("554-5.7.0 Filterstate is %d\r\n", filterstate);
+		reply("554 5.7.0 Contact postmaster@%s for more information.\r\n",
+			dom);
 		return 0;
 	case ACCEPT:
 	case TRUSTED:
@@ -794,14 +839,14 @@ startcmd(void)
 		n = 3;
 		for(l = rcvers.first; l; l = l->next)
 			n++;
-		av = malloc(n*sizeof(char*));
+		av = malloc(n * sizeof(char*));
 		if(av == nil){
-			reply("450 We're busy right now, try later\n");
+			reply("450 4.3.2 We're busy right now, try later\r\n");
 			s_free(cmd);
 			return 0;
 		}
 
-			n = 0;
+		n = 0;
 		av[n++] = s_to_c(cmd);
 		av[n++] = "-r";
 		for(l = rcvers.first; l; l = l->next)
@@ -810,12 +855,13 @@ startcmd(void)
 		/*
 		 *  start mail process
 		 */
-		pp = noshell_proc_start(av, instream(), outstream(), outstream(), 0, 0);
+		pp = noshell_proc_start(av, instream(), outstream(),
+			outstream(), 0, 0);
 		free(av);
 		break;
 	}
 	if(pp == 0) {
-		reply("450 We're busy right now, try later\n");
+		reply("450 4.3.2 We're busy right now, try later\r\n");
 		s_free(cmd);
 		return 0;
 	}
@@ -857,7 +903,7 @@ getaddr(Node *p)
 }
 
 /*
- *  add waring headers of the form
+ *  add warning headers of the form
  *	X-warning: <reason>
  *  for any headers that looked like they might be forged.
  *
@@ -872,26 +918,28 @@ forgedheaderwarnings(void)
 	nbytes = 0;
 
 	/* warn about envelope sender */
-	if(strcmp(s_to_c(senders.last->p), "/dev/null") != 0 && masquerade(senders.last->p, nil))
-		nbytes += Bprint(pp->std[0]->fp, "X-warning: suspect envelope domain\n");
+	if(strcmp(s_to_c(senders.last->p), "/dev/null") != 0 &&
+	    masquerade(senders.last->p, nil))
+		nbytes += Bprint(pp->std[0]->fp,
+			"X-warning: suspect envelope domain\n");
 
 	/*
-	 *  check Sender: field.  If it's OK, ignore the others because this is an
-	 *  exploded mailing list.
+	 *  check Sender: field.  If it's OK, ignore the others because this
+	 *  is an exploded mailing list.
 	 */
-	for(f = firstfield; f; f = f->next){
-		if(f->node->c == SENDER){
+	for(f = firstfield; f; f = f->next)
+		if(f->node->c == SENDER)
 			if(masquerade(getaddr(f->node), him))
-				nbytes += Bprint(pp->std[0]->fp, "X-warning: suspect Sender: domain\n");
+				nbytes += Bprint(pp->std[0]->fp,
+					"X-warning: suspect Sender: domain\n");
 			else
 				return nbytes;
-		}
-	}
 
 	/* check From: */
 	for(f = firstfield; f; f = f->next){
 		if(f->node->c == FROM && masquerade(getaddr(f->node), him))
-			nbytes += Bprint(pp->std[0]->fp, "X-warning: suspect From: domain\n");
+			nbytes += Bprint(pp->std[0]->fp,
+				"X-warning: suspect From: domain\n");
 	}
 	return nbytes;
 }
@@ -906,15 +954,12 @@ forgedheaderwarnings(void)
 int
 pipemsg(int *byteswritten)
 {
-	int status;
+	int n, nbytes, sawdot, status;
 	char *cp;
-	String *line;
-	String *hdr;
-	int n, nbytes;
-	int sawdot;
 	Field *f;
-	Node *p;
 	Link *l;
+	Node *p;
+	String *hdr, *line;
 
 	pipesig(&status);	/* set status to 1 on write to closed pipe */
 	sawdot = 0;
@@ -925,7 +970,7 @@ pipemsg(int *byteswritten)
 	 */
 	nbytes = 0;
 	nbytes += Bprint(pp->std[0]->fp, "From %s %s remote from \n",
-			s_to_c(senders.first->p), thedate());
+		s_to_c(senders.first->p), thedate());
 
 	/*
 	 *  add our own Received: stamp
@@ -978,7 +1023,8 @@ pipemsg(int *byteswritten)
 		if(senders.last == nil)
 			Bprint(pp->std[0]->fp, "From: /dev/null@%s\n", him);
 		else
-			Bprint(pp->std[0]->fp, "From: %s\n", s_to_c(senders.last->p));
+			Bprint(pp->std[0]->fp, "From: %s\n",
+				s_to_c(senders.last->p));
 	}
 	if(destination == 0){
 		Bprint(pp->std[0]->fp, "To: ");
@@ -1009,7 +1055,8 @@ pipemsg(int *byteswritten)
 	}
 
 	/* write anything we read following the header */
-	if(status == 0 && Bwrite(pp->std[0]->fp, cp, s_to_c(hdr) + s_len(hdr) - cp) < 0){
+	if(status == 0 &&
+	    Bwrite(pp->std[0]->fp, cp, s_to_c(hdr) + s_len(hdr) - cp) < 0){
 		piperror = "write error 2";
 		status = 1;
 	}
@@ -1063,8 +1110,8 @@ pipemsg(int *byteswritten)
 char*
 firstline(char *x)
 {
-	static char buf[128];
 	char *p;
+	static char buf[128];
 
 	strncpy(buf, x, sizeof(buf));
 	buf[sizeof(buf)-1] = 0;
@@ -1077,16 +1124,16 @@ firstline(char *x)
 int
 sendermxcheck(void)
 {
-	char *cp, *senddom, *user;
-	char *who;
 	int pid;
+	char *cp, *senddom, *user, *who;
 	Waitmsg *w;
 
 	who = s_to_c(senders.first->p);
 	if(strcmp(who, "/dev/null") == 0){
 		/* /dev/null can only send to one rcpt at a time */
 		if(rcvers.first != rcvers.last){
-			werrstr("rejected: /dev/null sending to multiple recipients");
+			werrstr("rejected: /dev/null sending to multiple "
+				"recipients");
 			return -1;
 		}
 		return 0;
@@ -1113,7 +1160,7 @@ sendermxcheck(void)
 		 * Could add an option with the remote IP address
 		 * to allow validatesender to implement SPF eventually.
 		 */
-		execl("/mail/lib/validatesender", "validatesender", 
+		execl("/mail/lib/validatesender", "validatesender",
 			"-n", nci->root, senddom, user, nil);
 		_exits("exec validatesender: %r");
 	default:
@@ -1127,7 +1174,8 @@ sendermxcheck(void)
 		return -1;
 	}
 	if(w->pid != pid){
-		werrstr("deferred: wait returned wrong pid %d != %d", w->pid, pid);
+		werrstr("deferred: wait returned wrong pid %d != %d",
+			w->pid, pid);
 		free(w);
 		return -1;
 	}
@@ -1150,35 +1198,34 @@ sendermxcheck(void)
 void
 data(void)
 {
-	String *cmd;
-	String *err;
 	int status, nbytes;
 	char *cp, *ep;
 	char errx[ERRMAX];
 	Link *l;
+	String *cmd, *err;
 
 	if(rejectcheck())
 		return;
 	if(senders.last == 0){
-		reply("503 Data without MAIL FROM:\r\n");
+		reply("503 2.5.2 Data without MAIL FROM:\r\n");
 		rejectcount++;
 		return;
 	}
 	if(rcvers.last == 0){
-		reply("503 Data without RCPT TO:\r\n");
+		reply("503 2.5.2 Data without RCPT TO:\r\n");
 		rejectcount++;
 		return;
 	}
 	if(!trusted && sendermxcheck()){
 		rerrstr(errx, sizeof errx);
 		if(strncmp(errx, "rejected:", 9) == 0)
-			reply("554 %s\r\n", errx);
+			reply("554 5.7.1 %s\r\n", errx);
 		else
-			reply("450 %s\r\n", errx);
+			reply("450 4.7.0 %s\r\n", errx);
 		for(l=rcvers.first; l; l=l->next)
 			syslog(0, "smtpd", "[%s/%s] %s -> %s sendercheck: %s",
-					him, nci->rsys, s_to_c(senders.first->p), 
-					s_to_c(l->p), errx);
+				him, nci->rsys, s_to_c(senders.first->p),
+				s_to_c(l->p), errx);
 		rejectcount++;
 		return;
 	}
@@ -1219,25 +1266,31 @@ data(void)
 	 */
 	if(status){
 		int code;
+		char *ecode;
 
 		if(strstr(s_to_c(err), "mail refused")){
-			syslog(0, "smtpd", "++[%s/%s] %s %s refused: %s", him, nci->rsys,
-				s_to_c(senders.first->p), s_to_c(cmd), firstline(s_to_c(err)));
+			syslog(0, "smtpd", "++[%s/%s] %s %s refused: %s",
+				him, nci->rsys, s_to_c(senders.first->p),
+				s_to_c(cmd), firstline(s_to_c(err)));
 			code = 554;
+			ecode = "5.0.0";
 		} else {
-			syslog(0, "smtpd", "++[%s/%s] %s %s %s%s%sreturned %#q %s", him, nci->rsys,
-				s_to_c(senders.first->p), s_to_c(cmd), 
-				piperror ? "error during pipemsg: " : "",
-				piperror ? piperror : "",
-				piperror ? "; " : "",
+			syslog(0, "smtpd", "++[%s/%s] %s %s %s%s%sreturned %#q %s",
+				him, nci->rsys,
+				s_to_c(senders.first->p), s_to_c(cmd),
+				piperror? "error during pipemsg: ": "",
+				piperror? piperror: "",
+				piperror? "; ": "",
 				pp->waitmsg->msg, firstline(s_to_c(err)));
 			code = 450;
+			ecode = "4.0.0";
 		}
 		for(cp = s_to_c(err); ep = strchr(cp, '\n'); cp = ep){
 			*ep++ = 0;
-			reply("%d-%s\r\n", code, cp);
+			reply("%d-%s %s\r\n", code, ecode, cp);
 		}
-		reply("%d mail process terminated abnormally\r\n", code);
+		reply("%d %s mail process terminated abnormally\r\n",
+			code, ecode);
 	} else {
 		/*
 		 * if a message appeared on stderr, despite good status,
@@ -1250,12 +1303,13 @@ data(void)
 				s_to_c(mailer), s_to_c(err));
 
 		if(filterstate == BLOCKED)
-			reply("554 we believe this is spam.  we don't accept it.\r\n");
-		else
-		if(filterstate == DELAY)
-			reply("554 There will be a delay in delivery of this message.\r\n");
+			reply("554 5.7.1 we believe this is spam.  "
+				"we don't accept it.\r\n");
+		else if(filterstate == DELAY)
+			reply("450 4.3.0 There will be a delay in delivery "
+				"of this message.\r\n");
 		else {
-			reply("250 sent\r\n");
+			reply("250 2.5.0 sent\r\n");
 			logcall(nbytes);
 		}
 	}
@@ -1279,15 +1333,14 @@ data(void)
 int
 rejectcheck(void)
 {
-
 	if(rejectcount > MAXREJECTS){
 		syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys);
-		reply("554 too many errors.  transaction failed.\r\n");
+		reply("554 5.5.0 too many errors.  transaction failed.\r\n");
 		exits("errcount");
 	}
 	if(hardreject){
 		rejectcount++;
-		reply("554 We don't accept mail from dial-up ports.\r\n");
+		reply("554 5.7.1 We don't accept mail from dial-up ports.\r\n");
 	}
 	return hardreject;
 }
@@ -1314,8 +1367,9 @@ mailerpath(char *p)
 String *
 s_dec64(String *sin)
 {
-	String *sout;
 	int lin, lout;
+	String *sout;
+
 	lin = s_len(sin);
 
 	/*
@@ -1338,12 +1392,12 @@ s_dec64(String *sin)
 void
 starttls(void)
 {
-	uchar *cert;
 	int certlen, fd;
+	uchar *cert;
 	TLSconn *conn;
 
 	if (tlscert == nil) {
-		reply("454 TLS not available\r\n");
+		reply("500 5.5.1 illegal command or bad syntax\r\n");
 		return;
 	}
 	conn = mallocz(sizeof *conn, 1);
@@ -1351,10 +1405,10 @@ starttls(void)
 	if (conn == nil || cert == nil) {
 		if (conn != nil)
 			free(conn);
-		reply("454 TLS not available\r\n");
+		reply("454 4.7.5 TLS not available\r\n");
 		return;
 	}
-	reply("220 Go ahead make my day\r\n");
+	reply("220 2.0.0 Go ahead make my day\r\n");
 	conn->cert = cert;
 	conn->certlen = certlen;
 	fd = tlsServer(Bfildes(&bin), conn);
@@ -1379,14 +1433,11 @@ starttls(void)
 void
 auth(String *mech, String *resp)
 {
-	Chalstate *chs = nil;
+	char *user, *pass, *scratch = nil;
 	AuthInfo *ai = nil;
-	String *s_resp1_64 = nil;
-	String *s_resp2_64 = nil;
-	String *s_resp1 = nil;
+	Chalstate *chs = nil;
+	String *s_resp1_64 = nil, *s_resp2_64 = nil, *s_resp1 = nil;
 	String *s_resp2 = nil;
-	char *scratch = nil;
-	char *user, *pass;
 
 	if (rejectcheck())
 		goto bomb_out;
@@ -1397,28 +1448,27 @@ auth(String *mech, String *resp)
 	if (authenticated) {
 	bad_sequence:
 		rejectcount++;
-		reply("503 Bad sequence of commands\r\n");
+		reply("503 5.5.2 Bad sequence of commands\r\n");
 		goto bomb_out;
 	}
 	if (cistrcmp(s_to_c(mech), "plain") == 0) {
-
 		if (!passwordinclear) {
 			rejectcount++;
-			reply("538 Encryption required for requested authentication mechanism\r\n");
+			reply("538 5.7.1 Encryption required for requested "
+				"authentication mechanism\r\n");
 			goto bomb_out;
 		}
 		s_resp1_64 = resp;
 		if (s_resp1_64 == nil) {
 			reply("334 \r\n");
 			s_resp1_64 = s_new();
-			if (getcrnl(s_resp1_64, &bin) <= 0) {
+			if (getcrnl(s_resp1_64, &bin) <= 0)
 				goto bad_sequence;
-			}
 		}
 		s_resp1 = s_dec64(s_resp1_64);
 		if (s_resp1 == nil) {
 			rejectcount++;
-			reply("501 Cannot decode base64\r\n");
+			reply("501 5.5.4 Cannot decode base64\r\n");
 			goto bomb_out;
 		}
 		memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64));
@@ -1430,10 +1480,10 @@ auth(String *mech, String *resp)
 		goto windup;
 	}
 	else if (cistrcmp(s_to_c(mech), "login") == 0) {
-
 		if (!passwordinclear) {
 			rejectcount++;
-			reply("538 Encryption required for requested authentication mechanism\r\n");
+			reply("538 5.7.1 Encryption required for requested "
+				"authentication mechanism\r\n");
 			goto bomb_out;
 		}
 		if (resp == nil) {
@@ -1451,34 +1501,34 @@ auth(String *mech, String *resp)
 		memset(s_to_c(s_resp2_64), 'X', s_len(s_resp2_64));
 		if (s_resp1 == nil || s_resp2 == nil) {
 			rejectcount++;
-			reply("501 Cannot decode base64\r\n");
+			reply("501 5.5.4 Cannot decode base64\r\n");
 			goto bomb_out;
 		}
 		ai = auth_userpasswd(s_to_c(s_resp1), s_to_c(s_resp2));
 		authenticated = ai != nil;
 		memset(s_to_c(s_resp2), 'X', s_len(s_resp2));
-	windup:
+windup:
 		if (authenticated)
-			reply("235 Authentication successful\r\n");
+			reply("235 2.0.0 Authentication successful\r\n");
 		else {
 			rejectcount++;
-			reply("535 Authentication failed\r\n");
+			reply("535 5.7.1 Authentication failed\r\n");
 		}
 		goto bomb_out;
 	}
 	else if (cistrcmp(s_to_c(mech), "cram-md5") == 0) {
-		char *resp;
 		int chal64n;
-		char *t;
+		char *resp, *t;
 
 		chs = auth_challenge("proto=cram role=server");
 		if (chs == nil) {
 			rejectcount++;
-			reply("501 Couldn't get CRAM-MD5 challenge\r\n");
+			reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
 			goto bomb_out;
 		}
 		scratch = malloc(chs->nchal * 2 + 1);
-		chal64n = enc64(scratch, chs->nchal * 2, (uchar *)chs->chal, chs->nchal);
+		chal64n = enc64(scratch, chs->nchal * 2, (uchar *)chs->chal,
+			chs->nchal);
 		scratch[chal64n] = 0;
 		reply("334 %s\r\n", scratch);
 		s_resp1_64 = s_new();
@@ -1487,7 +1537,7 @@ auth(String *mech, String *resp)
 		s_resp1 = s_dec64(s_resp1_64);
 		if (s_resp1 == nil) {
 			rejectcount++;
-			reply("501 Cannot decode base64\r\n");
+			reply("501 5.5.4 Cannot decode base64\r\n");
 			goto bomb_out;
 		}
 		/* should be of form <user><space><response> */
@@ -1495,7 +1545,7 @@ auth(String *mech, String *resp)
 		t = strchr(resp, ' ');
 		if (t == nil) {
 			rejectcount++;
-			reply("501 Poorly formed CRAM-MD5 response\r\n");
+			reply("501 5.5.4 Poorly formed CRAM-MD5 response\r\n");
 			goto bomb_out;
 		}
 		*t++ = 0;
@@ -1507,7 +1557,7 @@ auth(String *mech, String *resp)
 		goto windup;
 	}
 	rejectcount++;
-	reply("501 Unrecognised authentication type %s\r\n", s_to_c(mech));
+	reply("501 5.5.1 Unrecognised authentication type %s\r\n", s_to_c(mech));
 bomb_out:
 	if (ai)
 		auth_freeAI(ai);

+ 3 - 5
sys/src/cmd/upas/smtp/smtpd.y

@@ -62,8 +62,6 @@ cmd		: error
 			{ noop(); }
 		| 'q' 'u' 'i' 't' CRLF
 			{ quit(); }
-		| 't' 'u' 'r' 'n' CRLF
-			{ turn(); }
 		| 's' 't' 'a' 'r' 't' 't' 'l' 's' CRLF
 			{ starttls(); }
 		| 'a' 'u' 't' 'h' spaces name spaces string CRLF
@@ -71,7 +69,7 @@ cmd		: error
 		| 'a' 'u' 't' 'h' spaces name CRLF
 			{ auth($6.s, nil); }
 		| CRLF
-			{ reply("501 illegal command or bad syntax\r\n"); }
+			{ reply("500 5.5.1 illegal command or bad syntax\r\n"); }
 		;
 path		: '<' '>'			={ $$ = anonymous(); }
 		| '<' mailbox '>'		={ $$ = $2; }
@@ -147,7 +145,7 @@ dotnum		: snum '.' snum '.' snum '.' snum ={ $$ = cat(&$1, &$2, &$3, &$4, &$5, &
 number		: d		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
 		| number d	={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
 		;
-snum		: number		={ if(atoi(s_to_c($1.s)) > 255) print("bad snum\n"); } 
+snum		: number		={ if(atoi(s_to_c($1.s)) > 255) print("bad snum\n"); }
 		;
 spaces		: SPACE		={ $$ = $1; }
 		| SPACE	spaces	={ $$ = $1; }
@@ -173,7 +171,7 @@ a		: 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i'
 d		: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
 		;
 c		: a | d | notspecial
-		;		
+		;
 q		: a | d | special1 | notspecial | SPACE
 		;
 x		: a | d | special | notspecial | SPACE