home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / fj / sources / 906 next >
Encoding:
Internet Message Format  |  1992-12-21  |  30.1 KB

  1. Path: sparky!uunet!stanford.edu!sun-barr!sh.wide!wnoc-kyo!icspub!madoka!saitoh
  2. From: saitoh@madoka.ics.osaka-u.ac.jp (SAITOH akinori)
  3. Newsgroups: fj.sources
  4. Subject: edd  3.3 alpha
  5. Message-ID: <74834@icspub.ics.osaka-u.ac.jp>
  6. Date: 21 Dec 92 17:14:47 GMT
  7. Sender: news@icspub.ics.osaka-u.ac.jp
  8. Lines: 1332
  9.  
  10. $@Bg:eBg3X$NsnF#$G$9(J
  11.  
  12. $@8fL5:;BA$G$9!#(J
  13. edd$@$N%P!<%8%g%s%"%C%W$r<B$O$3$^$a$K$d$C$F$?$s$G$9$,!"(J
  14. $@8xI=$7K:$l$F$?$3$H$K5$IU$-$^$7$?!#(J
  15.  
  16. ver 3.3alpha $@$H$$$&$+!"(J 3.3beta $@$/$i$$$N0BDjEY$K$O$J$C$F$$$k$H;W$$$^$9!#(J
  17. $@%a%8%c!<%P!<%8%g%sHV9f$,>e$,$C$?$N$O!"(JRCS$@F3F~$NI{:nMQ$G$9!#(J
  18.  
  19. $@%P%0>pJs(J/$@2~NIMW@A$O4?7^$7$^$9(J
  20.  
  21. enjoy
  22.  
  23.     $@snF#(J@ics.osaka-u.ac.jp
  24.     -- $@$_$s$JIOK3$,0-$$$s$d(J
  25.  
  26. #! /bin/sh
  27. # This is a shell archive, meaning:
  28. # 1. Remove everything above the #! /bin/sh line.
  29. # 2. Save the resulting text in a file.
  30. # 3. Execute the file with /bin/sh (not csh) to create the files:
  31. #        edd.doc
  32. #        Makefile
  33. #        edd.c
  34. # This archive created:  Tue Dec 22 02:06:49 JST 1992
  35. export PATH; PATH=/bin:$PATH
  36. :
  37. :    File = edd.doc
  38. :
  39. echo shar: extracting "'edd.doc'" '( 6375 characters )'
  40. if test -f 'edd.doc'
  41. then
  42.     echo shar: will not over-write existing file "'edd.doc'"
  43. else
  44. cat > edd.doc << '!End-Of-edd.doc!'
  45. edd.doc
  46.  
  47.     $@snF#L@5*(J    saitoh@ics.osaka-u.ac.jp
  48. -----
  49. Tabel of contents
  50.  
  51. 1 Revision History
  52. 2 Introduction to edd
  53. 3 Installation
  54.  
  55. -----
  56.  
  57. 1. Revision history
  58. 1992  Dec 22 ver 3.3 alpha
  59. $@F~=PNO(J K$@%P%$%H?t$b%l%]!<%H$9$k$h$&$K$7$?!#(J
  60. help$@$rDI2C$7$?!#(J
  61. fsync$@%b!<%I$r$D$1$?!#(J
  62. $@=PNO$K(J PIPE WRITE ERROR $@$,7+$jJV$7$F5/$-$k$H!"(Jabort$@$9$k$h$&$K$7$?!#(J
  63.  
  64. 1991 Nov 11 ver 3.1
  65.  SCCS$@$G$N%=!<%94IM}$r3+;O$7$?$?$a%a%8%c!<%P!<%8%g%sHV9f$,JQ$o$C$F$7$^$C$?!#(J
  66.  
  67. $@%Q%G%#%s%0$N@_Dj%b!<%I$rJQ99$7$?!#(J
  68.  
  69.     pad    $@:G8e$N(J write$@$b(Jobs$@$K$J$k$h$&$K%Q%G%#%s%0$9$k!#(J
  70.     pad=size    $@:G8e$N(J write $@$,(J size $@$K$J$k$h$&$K%Q%G%#%s%0$9$k!#(J
  71.  
  72. $@$3$l$K$H$b$J$$!"=>Mh$N(J padunit=size $@%*%W%7%g%s$O(J USAGE$@$+$i>C5n$7$?!#(J
  73. $@;XDj$5$l$l$PG'<1$9$k!#(J
  74.  
  75.  slow start $@$r%*%U$K$G$-$k$h$&$K$7$?!#(J
  76.  
  77. $@%Q%U%)!<%^%s%98~>e$N$?$a!"%=%1%C%H$KBP$7$F%P%C%U%!%5%$%:@_Dj(J
  78. $@$r9T$J$&$h$&$K$7$?!#8=>u$G$O(J 64Kbye.
  79.  
  80. $@<B$O!"$7$P$i$/A0$+$i%5%V%W%m%;%9$rF~=PNO$NBP>]$H$G$-$k$h$&$K(J
  81. $@$7$F$"$k!#(J if=file of=file $@$NBe$o$j$K(J ip=command op=command$@%*(J
  82. $@%W%7%g%s$r;H$&!#$?$H$($P!"(J
  83.  
  84. tar cf - .|compress |edd of=/dev/rst8 pad=1b obs=200b bs=400k
  85. $@$O!"(J
  86. edd ip="tar cf - .|compress" of=/dev/rst8 pad=1b obs=200b bs=400k
  87. $@$H=q$1$k$7!"(J
  88. edd if=/dev/rst8 ibs=200b bs=400k |uncompress |tar xfp - .
  89. $@$O!"(J
  90. edd op="uncompress|tar xf -"  if=/dev/rst8 ibs=200b bs=400k
  91. $@$H=q$1$k!#(J
  92.  
  93. $@$?$@$7!"M>$j8O$l$?5!G=$G$O$J$$$N$GCm0U!#(J
  94.  
  95.  
  96. 1990 Nov  6 ver 2.7
  97.  $@%\%j%e!<%`J,3d$N%P%0$r=$@5(J
  98.  $@@)8B;v9`(J: $@%\%j%e!<%`%5%$%:$O(J 2GB$@L$K~$G$"$k$3$H!#(J
  99.  
  100. 1990 Jul 20 ver 2.6
  101.  ver 2.1$@!A(J2.6$@$G$NJQ99(J
  102.  $@F~=PNO%P%$%H?t$r%l%]!<%H$9$k$h$&$K$7$?!#(J dd$@$N$h$&$J(J read/write$@%7%9%F%`(J
  103. $@%3!<%k;HMQ2s?t$G$O$J$$$N$GCm0U!#(J
  104.   SUN OS$@$N(J rst $@$O!"%F!<%WKvC<$X$N=q$-9~$_$KBP$7$F(J 0 $@$r$+$($9!#$=$3$G(J
  105. write$@%7%9%F%`%3!<%k$NJV$jCM$,(J0$@$J$i$P%F!<%WKv07$$$K$9$k$h$&$K$7$?!#(J SUN
  106. OS$@0J30$N(JOS$@$G$O%F!<%WKv$O(J I/O ERROR$@$K$J$k$N$G$b$H$b$HLdBj$J$$!#(J
  107.  /bin/sh$@$NCf$G!"%Q%$%W%i%$%s$N%a%s%P!<$H$7$F5/F0$5$l$?;~$K%"%\!<%H$7$h$&(J
  108. $@$H$9$k$H%O%s%0$9$k!#%"%\!<%H;~$O(J wait()$@$7$J$$$h$&$KJQ99!#(J
  109.  Slow start
  110.  System V $@$KBP1~!#(J
  111.  usage $@=PNO2~NI!#(J
  112.  Copyright notice $@$r%P%$%J%jCf$K4^$a$?!#(J
  113.  Some undocumented feature
  114.  $@%Q%G%#%s%0$NC10L$N;XDj$rDI2C!#%G%U%)%k%H$O(J obs$@!#(J
  115.  
  116. 1990 Jan 6 ver2.0
  117.   ver 1.0 $@$G$O!"?F;R$N%W%m%;%94V$N%W%m%H%3%k$NITHw$K$h$j!"%(%i!<$,$*$-$F(J
  118. $@$$$J$$$N$K%(%i!<%a%C%;!<%8(J(close: not owner$@$J$I(J)$@$r=P$9$3$H$,$"$j$^$7$?!#(J
  119. ver 2.0 $@$G$O!"$3$NITHw$r2r>C$7$?$D$b$j$G$9!#$=$l$+$i!"%^%k%A%\%j%e!<%`BP(J
  120. $@1~$K$b<j$rF~$l$F$"$j$^$9$,!"%P%0=P$7$,40N;$7$F$$$^$;$s$N$G(J undocumented
  121. feature $@$H$$$&$3$H$K$7$F$*$-$^$9!#(J
  122.  
  123. -----------
  124. 2 Introduction to edd
  125.  
  126.  edd$@$O!"<'5$%F!<%WF~=PNO$r9bB.2=$9$k$?$a$N%P%C%U%!5!G=$rDs6!$7$^$9!#(Jedd
  127. $@$OFs$D$N%W%m%;%9$K%U%)!<%/$7!"0lJ}$,=PNO$7$F$$$k4V$KB>J}$OF~NO$rB3$1$^$9!#(J
  128. $@0z?t$N7A<0$O(J dd $@$K;w$;$F$"$j$^$9!#(J edd$@$H(Jrsh$@$rAH$_9g$o$;$k$H!"9bB.$K(J tape
  129. to tape copy $@$r9T$J$&;v$,$G$-$^$9!#(J
  130.  
  131.   edd 1.0 $@$O!"F~NO$r(J obs $@$K$"$o$;$k$h$&$K%Q%G%#%s%0$7$^$9!#$3$N$?$a!"(Jedd
  132. $@$r7PM3$7$?%G!<%?$r(J tar$@$J$I$NF~NO$H$7$FM?$($k$H(J broken pipe $@$G(Jedd $@$,%"%\!<(J
  133. $@%H$9$k$3$H$,$"$j$^$7$?!#(Jedd ver 2.0 $@$G$O!"%*%W%7%g%s(J pad $@$rM?$($?$H$-$@(J
  134. $@$1%Q%C%G%#%s%0$r9T$&$h$&$K;EMM$rJQ99$7$^$7$?!#%G%U%)%k%H$G$O%Q%G%#%s%0$7(J
  135. $@$^$;$s!#$^$?(J edd 2.0 $@$G$O(J SIGPIPE $@$r%H%i%C%W$7$F$$$^$9$N$G!"(J broken pipe
  136. $@$,5/$-$F$b%"%\!<%H$9$k$3$H$J$/!"%(%i!<%a%C%;!<%8(J( broken pipe)$@$r=PNO$7$F(J
  137. $@$G$-$k8B$jB.$d$+$KF0:n$r40N;$7$^$9!#(JBroken pipe$@$N%a%C%;!<%8$,J#?t=PNO$5(J
  138. $@$l$?$H$-$O!"F~NO%G!<%?$NESCf(J($@:G8e$N%G!<%?%V%m%C%/$G$J$$$H$3$m(J)$@$G(J broken
  139. pipe $@$,5/$-$?$3$H$r0UL#$7$^$9!#(J
  140.  
  141. $@Nc(J:
  142.  
  143. dump 0uf - /usr  |edd of=/dev/rst8 obs=200b bs=600b ibs=20b
  144.  
  145. rsh remote -n edd if=/dev/rst0 ibs=63k bs=300kk | tar xvfBp -
  146.  
  147. edd if=/dev/rst0 ibs=126b bs=630b \
  148.  | rsh remote edd of=/dev/rst8 obs=100k bs=400k
  149.  
  150. tar cf - .|compress|edd pad=1b of=/dev/rst8 obs=200b bs=400k
  151.  
  152.   ibs,obs $@$G!"F~=PNO$N%V%m%C%-%s%0%U%!%/%?$r;XDj$7$^$9!#>/$J$/$H$b0lJ}$O(J
  153. $@;XDj$7$J$1$l$P$J$j$^$;$s!#0lJ}$,>JN,$5$l$k$HB>J}$HF1$8CM$,$H$i$l$^$9!#(J
  154.  
  155.   bs$@$G%P%C%U%!%5%$%:$r;XDj$7$^$9!#(Jdd$@$G$O!"(Jbs=$@$O(J obs$@$H(Jibs$@$rF1$8CM$K@_Dj$9(J
  156. $@$k$?$a$N$b$N$G$7$?$,!"(J edd$@$G$O0c$$$^$9!#%P%C%U%!%5%$%:$O(Jibs$@$H(Jobs$@$N8xG\?t(J
  157. $@$G$J$1$l$P$J$j$^$;$s!#$=$&$G$J$$>l9g!"%V%m%C%/%5%$%:$r@Z$j>e$2$FBP1~$7$h(J
  158. $@$&$H$7$^$9$,!"$=$l$K<:GT$9$k$H%"%\!<%H$7$^$9!#(J
  159.  $@Nc(J:
  160.   ibs=126b bs=300k $@$H$9$k$H!"(J Block size rounded up to 322560 $@$H$$$&%a%C(J
  161. $@%;!<%8$H6&$K%V%m%C%/%5%$%:$r(J 315K$@$K@Z$j>e$2$^$9!#(J
  162.  
  163.  ibs,obs,bs $@$N;XDj$NC10L$O%P%$%H$G$9!#KvHx$KC10L$r$D$1$k;v$b$G$-$^$9!#(J
  164. $@G'<1$9$kC10L$O!"(Jb(block=512byte),K(=1024byte),M(mega-byte)$@$G$9!#(J
  165.  
  166.   edd$@$OFs$D$K%U%)!<%/$7$^$9$N$G!"(Jedd$@$rF0:n$5$;$k7W;;5!$N<B%a%b%j$O!"(Jbs$@$G(J
  167. $@;XDj$7$?%P%C%U%!%5%$%:$N(J2$@G\0J>e6u$$$F$$$J$1$l$P$J$j$^$;$s!#$5$b$J$$$H5^7c(J
  168. $@$K%9%k!<%W%C%H$,Dc2<$7$^$9!#(Jbs$@$O!"%F!<%W$N%G!<%?E>AwB.EY$+$i5U;;$7$F(J
  169. 1$@ICJ,0J>e!"=PMh$l$P?tICJ,;XDj$9$k$N$,NI$$$H;W$o$l$^$9!#(J
  170. $@L50G$KBg$-$$CM$r;XDj$7$F$bL5BL$G$9!#(J
  171.  
  172.   rewind $@%*%W%7%g%s$r;XDj$9$k$H!"F~=PNO$r%/%m!<%:$7$?D>8e$K(J1$@2s!"FI$_$@$7(J
  173. $@%b!<%I$G%*!<%W%s$7$F$9$0%/%m!<%:$7$^$9!#(J
  174.  
  175.  $@%9%H%j!<%_%s%0%F!<%W$K(J 512$@%P%$%H$NG\?t$G$J$$%G!<%?$r=q$/>l9g$K$O!"I,$:(J
  176. pad $@%*%W%7%g%s$r$D$1$F$/$@$5$$!#$5$b$J$$$H$$%G!<%?$N:G8e$G=q$-9~$_%(%i!<(J
  177. $@$r5/$3$7$^$9!#(J
  178.  
  179.  $@Nc(J:
  180.  tar cfB - X.V11R4 | compress | edd of=/dev/rst8 obs=20b bs=500k pad=1b
  181.  
  182.  Slow start $@$O32$,$J$$$O$:$G$9$,!"5$$KF~$i$J$$$J$i(J noss $@%*%W%7%g%s$GM^@)(J
  183. $@$9$k$3$H$,$G$-$^$9!#(J
  184.  
  185. $@=PNO@h$,%F!<%W$G$O$J$/!"8w<'5$%G%#%9%/>e$N%l%.%e%i!<%U%!%$%k(J
  186. $@$J$I$@$H!"%G%#%9%/(J I/O$@%P%C%U%!%-%c%C%7%e$r;H$$2L$?$9$3$H$,$"$j$^$9!#(J
  187. $@$3$l$OL5BL$@$7!"(JSUN OS, NEWS OS$@$J$I$G$O%f!<%6%W%m%;%96u4V$r05Gw$9$k$N$G(J
  188. $@$&$l$7$/$"$j$^$;$s!#(J fsync $@%*%W%7%g%s$G2sHr$G$-$^$9!#(J
  189.  
  190.  
  191. 3. Installation
  192.  $@;HMQ!&G[I[>r7o$J$I$K$D$$$F$O(J edd.c$@@hF,$N%3%a%s%H$r;2>H$N$3$H!#(J
  193.  
  194. $@!&%3%s%Q%$%k(J
  195. BSD $@$"$k$$$O(J SUN OS
  196.  cc edd.c -o edd
  197.  
  198. System V
  199.  cc -DSYSV -DNBPG=4096 edd.c -o edd.c 
  200.  NBPG$@$O2>A[5-21$N%Z!<%8%5%$%:$r@_Dj$9$k$3$H!#(J
  201.  
  202. ----
  203. !End-Of-edd.doc!
  204. if test 6375 -ne "`wc -c < 'edd.doc'`"
  205. then
  206.      echo shar: error transmitting "'edd.doc'" '(should have been 6375 characters)'
  207. fi
  208. fi
  209. :
  210. :    File = Makefile
  211. :
  212. echo shar: extracting "'Makefile'" '( 219 characters )'
  213. if test -f 'Makefile'
  214. then
  215.     echo shar: will not over-write existing file "'Makefile'"
  216. else
  217. cat > Makefile << '!End-Of-Makefile!'
  218. CFLAGS = -O
  219. # for System V
  220. # CFLAGS= -O -DSYSV -DNBPG=4096
  221.  
  222. edd : edd.c
  223.     cc $(CFLAGS) edd.c -o edd
  224.  
  225. clean:
  226.     rm -f edd.o core edd
  227.  
  228. shar: edd.shar
  229.  
  230. edd.shar : Makefile edd.c edd.doc
  231.     shar edd.doc Makefile edd.c >edd.shar
  232. !End-Of-Makefile!
  233. if test 219 -ne "`wc -c < 'Makefile'`"
  234. then
  235.      echo shar: error transmitting "'Makefile'" '(should have been 219 characters)'
  236. fi
  237. fi
  238. :
  239. :    File = edd.c
  240. :
  241. echo shar: extracting "'edd.c'" '( 22080 characters )'
  242. if test -f 'edd.c'
  243. then
  244.     echo shar: will not over-write existing file "'edd.c'"
  245. else
  246. cat > edd.c << '!End-Of-edd.c!'
  247. #define version " 3.3 alpha"
  248. #ifndef version
  249. #define version rcsid
  250. #endif
  251.  
  252. /*
  253.  * Enhanced dd, Double bufferrd.
  254.  * 
  255.  * (C) Copyright 1989 SAITOH,Akinori saitoh@osaka-u.ac.jp 
  256.  *
  257.  * Permit anyone to use, modify, re-distribute this software.
  258.  * $@$3$N%=%U%H%&%'%"$r:#8eL54|8B$K<+M3$KMxMQ!"2~B$!":FG[I[$9$k;v$r5v$7$^(J
  259.  * $@$9!#(J
  260.  * $@$3$N%=%U%H%&%'%"$O!"(JAT&T System V $@5Z$S(JUCB 4.3BSD $@$N%=!<%9%3!<%I%i%$%;(J
  261.  * $@%s%9$r<hF@$7$F$$$k7W;;5!$r;H$C$F3+H/$7$^$7$?!#$7$+$7!"$3$N%=%U%H%&%'(J
  262.  * $@%"$O!"(JAT&T ,BSD $@$K8B$i$:!"B><T$NCx:n8"$,5Z$V%=!<%9%W%m%0%i%`$OMxMQ$7(J
  263.  * $@$F$$$^$;$s!#(J
  264.  * ver 2.0  Sat Jan  6  1990
  265.  * correct termination protocol to shut up illegal error message
  266.  * ver 2.1  Tue Jan  9 1990
  267.  * Bug fix
  268.  * Ver 2.2 Thu Apr 12 1990
  269.  * System V port
  270.  * On BSD or SUN OS: cc edd.c -o edd
  271.  * On System V : cc -DSYSV -DNBPG=4096 edd.c -o edd.c 
  272.  * 4096 should be changed to your virtual memory page size
  273.  * ver 2.3 Jun  24 1990; bug(hung on abort) fix + message change
  274.  * ver 2.4 Jul 4   1990; add bytes report;
  275.  * ver 2.5 Jul 5   1990; fake SUN rst media end
  276.  * ver 2.6 Jul 20  1990; add padunit option
  277.  * ver 2.7 Nov  6  1990; multivolume bug fix, protocol change
  278.  * ver 3.1 Nov 7  1991; change pad flag, Socket buffer size, on err exit
  279.  * ver 3.3 Dec 22 1992; Add help message, etc.
  280.  *  
  281.  */
  282. static char    *copyright[] = {
  283.     "(C) Copyright 1989 SAITOH,Akinori saitoh@ics.osaka-u.ac.jp\n",
  284. "Permit anyone to use, modify, re-distribute this software.\n"};
  285.  
  286. static char rcsid[]= "$Header:";
  287.  
  288. #include <stdio.h>
  289. #include <ctype.h>
  290. #include <signal.h>
  291. #include <sys/types.h>
  292. #include <sys/param.h>
  293. #include <sys/socket.h>
  294. #ifdef SYSV
  295. #include <fcntl.h>
  296. #include <string.h>
  297. #else
  298. #include <sys/file.h>
  299. #include <strings.h>
  300. #endif
  301. #include <sys/errno.h>
  302. extern int      errno;
  303.  
  304.  
  305. usage(s)
  306.     char           *s;
  307. {
  308.     fputs(s, stderr);
  309.     fprintf(stderr, "edd version %s\n", version);
  310.     fputs(
  311. "edd [if=file] [of=file] [ibs=inblk] [obs=outblk] [bs=bufsiz] \\\n\
  312. \t[pad[=subopt,subopt,,]] [rewind] [volume=size] [concat=n] \\\n\
  313. \t[isbs=isockbuf] [osbs=osockbuf]\n",
  314.           stderr);
  315.     fputs("Obs must be a multiple of ibs.\n", stderr);
  316.     xerror(s);
  317. }
  318.  
  319. extern char    *valloc();    /* page aligned alloc */
  320. char           *databuf;
  321. int             infd = 0, outfd = 1, volcount = 0, involcount = 0, notty;
  322. int             pipein = -1, pipeout = -1, parent = -1;
  323. FILE           *ftty;
  324. int             inbytes = 0, outbytes = 0;
  325. unsigned long   inbytes_total = 0, outbytes_total = 0;
  326.  
  327.  
  328. #define WHOAMI (parent ? "parent" : "child")
  329. #define IN_OK 'I'
  330. #define OUT_OK 'O'
  331. #define EOF_APPEAR 'E'
  332.  
  333. #define ISBS_DEFAULT    8192
  334. #define OSBS_DEFAULT    8192
  335. #define ISBS_MAX    32768
  336. #define OSBS_MAX    32768
  337. #define MAXEPIPE    3
  338.  
  339. long            obs = 0, ibs = 0, bs = 0, isbs=0, osbs=0;
  340. int             concat = 1, verbose = 0, noss = 0, dofsync=0;
  341. unsigned long   volume = 0;
  342. int             bunit;
  343. char           *infile = NULL;
  344. char           *outfile = NULL;
  345. char           *inproc = NULL;
  346. char           *outproc = NULL;
  347. int             rewindtape = 0;
  348. int             padunit = 0;
  349. int             padmode = 0;
  350. #define PAD_NORMAL    1
  351. #define PAD_TAR    2
  352.  
  353.  
  354. #define INFILE ((infile==NULL)?"stdin":infile)
  355. #define OUTFILE ((outfile==NULL)?"stdout":outfile)
  356.  
  357. #ifndef MAX
  358. #define MAX(a,b) ((a)>(b)?(a):(b))
  359. #endif
  360. #ifndef MIN
  361. #define MIN(a,b) ((a)<(b)?(a):(b))
  362. #endif
  363.  
  364. char *numparse();
  365. int setpad();
  366. int help();
  367.  
  368. struct {
  369.     char           *name;
  370.     enum {
  371.         NUM, STR, BOOL,SPL
  372.     }               attrib;
  373.     char           *objptr;
  374.     char           *msg;
  375. }               options[] = {
  376.     { "help", SPL, (char *) help, "display help message"}, 
  377.     { "-help", SPL, (char *) help, "display help message"}, 
  378.     { "of", STR, (char *) &outfile, "output file"},
  379.     { "if", STR, (char *) &infile, "input file"},
  380.     { "op", STR, (char *) &outproc, "output to process"},
  381.     { "ip", STR, (char *) &inproc, "input from process"},
  382.     { "obs", NUM, (char *) &obs, "output block size"},
  383.     { "ibs", NUM, (char *) &ibs, "input block size"},
  384.     { "osbs", NUM, (char *) &osbs, "output socket buffer size"},
  385.     { "isbs", NUM, (char *) &isbs, "input socket buffer size"},
  386.     { "bs", NUM, (char *) &bs, "buffer size"},
  387.     { "concat", NUM, (char *) &concat, "concat # input volume"},
  388.     { "volume", NUM, (char *) &volume, "volume size"},
  389.     { "verbose", BOOL, (char *) &verbose, ""},
  390.     { "noss", BOOL, (char *) &noss, "NO Slow Start"},
  391.     { "fsync", BOOL, (char *) &dofsync, "fsync on each write"},
  392.     { "rewind", BOOL, (char *) &rewindtape, "rewind input device at start and end"},
  393.     { "pad", SPL, (char *) setpad, "padding mode. pad, pad=2b"}, 
  394.     { "padunit", NUM, (char *) &padunit, "for backward compatibility"},
  395.     { "", NUM, NULL, ""},
  396. };
  397.  
  398.  
  399. char           *progname;
  400.  
  401. main(argc, argv)
  402.     int             argc;
  403.     char           *argv[];
  404. {
  405.     char           *s;
  406.     int             inputeof;
  407.  
  408.     progname = argv[0];
  409.     while ((s = index(progname, '/')) != NULL)
  410.         progname = s + 1;
  411.     if (argc < 2)
  412.         usage("");
  413.     notty = 0;
  414.     setbuf(stderr, NULL);
  415.     if ((ftty = fopen("/dev/tty", "r")) == NULL) {
  416.         notty = 1;
  417.         if ((ftty = fopen("/dev/null", "r")) == NULL) {
  418.             perror("/dev/null");
  419.             xerror("/dev/null open failed\n");
  420.         }
  421.     } else if (freopen("/dev/tty", "w", stderr) == NULL) {
  422.         perror("/dev/tty");
  423.         xerror("control tty open failed\n");
  424.     }
  425.     argparse(argc, argv);
  426.     optioncheck();
  427.     if (volume == 0) {
  428.         volume = (1024 * 1024 * 1024) / bs;
  429.         volume *= bs;
  430.     }
  431.     if ((databuf = valloc((unsigned) bs)) == NULL) {
  432.         xerror("can not alloc buffer\n");
  433.     }
  434.     if (verbose) {
  435.         fprintf(stderr, "ibs=%db obs=%db bs=%db\n",
  436.             ibs / 512, obs / 512, bs / 512);
  437.     }
  438.     signal(SIGPIPE, SIG_IGN);
  439.     volcount = 1;
  440.     involcount = 1;
  441.     openinput();
  442.     if (infd < 0)
  443.         xerror("input open failed\n");
  444.     if (outfile != NULL)
  445.         outfd = -1;
  446.     else
  447.         outfd = openoutput();
  448.     
  449.     for (inputeof = 0; concat > 0;) {
  450.         register int    nin, nout;
  451.         register unsigned long ebs;
  452.         register int    last;
  453.  
  454.         if (infd < 0) {
  455.             involcount++;
  456.             openinput();
  457.             inbytes = 0;
  458.             inputeof = 0;
  459.             if (infd < 0)
  460.                 xerror("input open failed\n");
  461.         }
  462.         if (outfd < 0) {/* end of out volume */
  463.             openoutput();
  464.             outbytes = 0;
  465.         }
  466.         setup_pipe();
  467.         if(!parent)
  468.             inbytes=outbytes=0;
  469.         bzero(databuf, bs);
  470.         if (noss)
  471.             ebs = bs;
  472.         else {
  473.             for (ebs = bunit; ebs < bs / 16; ebs *= 2);
  474.         }
  475.         for (last = 0; !last;) {
  476.             if (ebs > bs)
  477.                 ebs = bs;
  478.             if (parent) {
  479.                 if (outbytes + ebs * 2 > volume/2)
  480.                     last++;
  481.             } 
  482.             if (get_token(IN_OK, EOF_APPEAR) == EOF_APPEAR) {
  483.                 nin = 0;
  484.                 if (!parent) 
  485.                     goto child_doexit;
  486.                     /* wait child write complete */
  487.                 (void) get_token(OUT_OK, OUT_OK);
  488.                 inputeof++;
  489.                 break;
  490.             }
  491.             nin = fillbuffer(infd, databuf, ebs, ibs);
  492.             if (nin < ebs) {
  493.                 inputeof++;
  494. if (verbose) {
  495. fprintf(stderr,"%s:%s:nin=%d,ebs=%d,inputeof++\n", progname,
  496.     WHOAMI, nin,ebs);
  497. }
  498.             }
  499.             if (nin < 0) {
  500.                 if (inbytes != 0)
  501.                     xerror("read error\n");
  502.                 /* fake eof */
  503.                 put_token(EOF_APPEAR, 0);
  504.                 goto read_error_at_top;
  505.             }
  506.             inbytes += nin;
  507.             if (nin == 0 && inbytes == 0 && inproc != NULL) {
  508.                 fprintf(stderr,
  509.                     "%s:%s:Got null input from program\n", progname,
  510.                     progname);
  511.                 /* fake eof */
  512.                 put_token(EOF_APPEAR, 0);
  513.                 goto read_error_at_top;
  514.             }
  515.             if (verbose) {
  516.                 fprintf(stderr,"%s:%s:got %d bytes\n", progname,
  517.                     WHOAMI, nin);
  518.             }
  519.             if (nin == ebs && !last){    /* not outvolume end */
  520.                 put_token(IN_OK, 0);
  521.             }else {
  522.                 put_token(EOF_APPEAR, 0);
  523.             }
  524.  
  525.             if (nin % obs) {
  526.                 bzero(databuf + nin, obs - (nin % obs));
  527.             }
  528.             (void) get_token(OUT_OK, OUT_OK);
  529.             if(nin==0)
  530.                 nout=0;
  531.             else {
  532.                 nout = ewrite(outfd, databuf, nin, obs);
  533.                 if (nout < 0) {
  534.                     xerror("aborting\n");
  535.                 }
  536.             }
  537.             if (verbose) {
  538.                 fprintf(stderr, "%s:%s:wrote %d bytes\n",
  539.                     progname, WHOAMI, nout);
  540.                 fflush(stderr);
  541.             }
  542.             outbytes += nout;
  543.             if (! inputeof && !last || !parent)
  544.                 put_token(OUT_OK, 0);
  545.             if (inputeof)
  546.                 break;
  547.             if (nout > nin) {    /* padding can occur only  on
  548.                          * end */
  549.                 break;
  550.             }
  551.             ebs *= 2;
  552.         }
  553.         if (!parent) {
  554.     child_doexit:
  555.             put_int(inbytes);
  556.             put_int(outbytes);
  557.             child_exit(0);
  558.             /* never return */
  559.         }
  560.         inbytes += get_int();
  561.         outbytes += get_int();
  562.         if (inputeof) {    /* input eof */
  563.             inbytes_total += inbytes;
  564.             inbytes = 0;
  565.             closeinput();
  566.             infd = -1;
  567.             concat--;
  568.         }
  569.         if (last || concat <= 0) {    /* end of out volume */
  570.             outbytes_total += outbytes;
  571.             outbytes = 0;
  572.             closeoutput();
  573.             outfd = -1;
  574.             volcount++;
  575.         }
  576.         disconnect_child();
  577.         continue;
  578.  
  579. read_error_at_top:
  580.         disconnect_child();
  581.         reopeninput();
  582.         inbytes = 0;
  583.     }
  584.     close(pipein);
  585.     close(pipeout);
  586.     if (ftty != NULL) {
  587.         fprintf(stderr, "%d blks+%d bytes in (%d KB)\n",
  588.             inbytes_total / ibs, inbytes_total % ibs
  589.             , (inbytes_total+1023) / 1024);
  590.         fprintf(stderr, "%d blks+%d bytes out (%d KB)\n",
  591.             outbytes_total / obs, outbytes_total % obs
  592.             , (outbytes_total+1023) / 1024);
  593.     }
  594.     if (parent)
  595.         wait(0);
  596.     exit(0);
  597. }
  598.  
  599. help()
  600. {
  601.     char  *pa, *po;
  602.     int    i;
  603.  
  604.     fprintf(stderr, "option parameters for edd\n");
  605.     for (i = 0; options[i].objptr != NULL; i++)
  606.         fprintf(stderr,"%s\t: %s\n", options[i].name, options[i].msg);
  607.     exit(1);
  608. }
  609.  
  610.  
  611. disconnect_child()
  612. {
  613.     put_token(EOF_APPEAR, 0);
  614.     close(pipein);
  615.     close(pipeout);
  616.     {
  617.         int             st;
  618.         while ((st = wait(0)) > 0 && st != parent);
  619.     }
  620. }
  621.  
  622. child_exit(e)
  623. {
  624.     if (verbose)
  625.         fprintf(stderr, "%s:child pid=%d: exiting\n", progname, getpid());
  626.     /* wait parent done */
  627.     if (get_token(EOF_APPEAR, -1) == EOF_APPEAR)
  628.         (void) get_token(EOF_APPEAR, -1);
  629.     if (verbose)
  630.         fprintf(stderr, "%s:child pid=%d: exit\n", progname, getpid());
  631.     exit(e);
  632. }
  633.  
  634. optioncheck()
  635. {
  636.  
  637.     if (inproc != NULL) {
  638.         infile = inproc;
  639.     }
  640.     if ((infile == NULL) && (concat != 1)) {
  641.         xerror("Can not concat stdin");
  642.     }
  643.     if (outproc != NULL) {
  644.         outfile = outproc;
  645.     }
  646.     if ((outfile == NULL) && (volume != 0)) {
  647.         xerror("Can not split stdout");
  648.     }
  649.     if (concat < 1)
  650.         xerror("Illegai concat value");
  651.     if (bs <= 0) {
  652.         bs = MAX(ibs, obs);
  653.     }
  654.     if (ibs <= 0) {
  655.         ibs = obs > 0 ? obs : bs;
  656.     }
  657.     if (obs <= 0) {
  658.         obs = ibs > 0 ? ibs : bs;
  659.     }
  660.     if (bs <= 0 || bs < obs || bs < ibs)
  661.         usage("Illegal buffersize\n");
  662.     if (ibs <= 0)
  663.         usage("illegal ibs\n");
  664.     if (obs <= 0)
  665.         usage("illegal obs\n");
  666.     {
  667.         int             x, y;
  668.  
  669.         x = ibs;
  670.         y = obs;
  671.         while (x != y)
  672.             if (x > y)
  673.                 x -= y;
  674.             else
  675.                 y -= x;
  676.         bunit = (ibs / x) * obs;
  677.     }
  678.     if (bs % ibs || bs % obs) {
  679.         bs = ((bs / bunit) + 1) * bunit;
  680.         fprintf(stderr, "%s:Buffer size rounded up to %d\n", progname, bs);
  681.     }
  682.     if (bs % ibs) {
  683.         usage("bs bust be a multiple of ibs\n");
  684.     }
  685.     if (bs % obs) {
  686.         usage("bs bust be a multiple of obs\n");
  687.     }
  688.     if (padmode && padunit == 0)
  689.         padunit = obs;
  690.     if(isbs==0 ) {
  691.         if(ibs <= ISBS_MAX)
  692.             isbs=ibs;
  693.         else
  694.             isbs=ISBS_DEFAULT;
  695.     }
  696.     if(osbs==0 ) {
  697.         if(obs <= OSBS_MAX)
  698.             osbs=obs;
  699.         else
  700.             osbs=OSBS_DEFAULT;
  701.     }
  702. }
  703.  
  704. /*
  705.  * read(infd) (ibs * count)bytes try to get ibs bytes on each read except
  706.  * last flagment.
  707.  * 
  708.  * return:    read BYTES if no error -1 on read error
  709.  */
  710. fillbuffer(infd, buf, bytes, ibs)
  711.     char           *buf;
  712.     register        bytes, ibs;
  713. {
  714.     register char  *bufp;
  715.     register int    n=0;
  716.  
  717.     for (bufp = buf; bytes > 0;) {
  718.         n = read(infd, bufp, bytes < ibs ? bytes : ibs);
  719.         if (n < 0) {
  720.             char            msg[BUFSIZ];
  721.             sprintf(msg, "%s:%s read %s", progname, WHOAMI, INFILE);
  722.             perror(msg);
  723.             break;
  724.         }
  725.         if (n == 0)
  726.             break;
  727.         bufp += n;
  728.         bytes -= n;
  729.     }
  730.     if (n >= 0 || buf != bufp)
  731.         return (bufp - buf);
  732.     else
  733.         return -1;
  734. }
  735.  
  736. closeinput()
  737. {
  738.     if (verbose) {
  739.         fprintf(stderr, "%s:%s:closing input\n", progname, parent ? "parent" : "child");
  740.         fflush(stderr);
  741.     }
  742.     if (infile == NULL)
  743.         return;
  744.     if (close(infd) < 0 && parent)
  745.         perror("close");
  746.     if (inproc != NULL) {
  747.         int             st;
  748.         st = wait(0);
  749.     }
  750.     if (!rewindtape || !parent)
  751.         return;
  752.     if ((infd = open(infile, O_RDONLY)) >= 0)
  753.         close(infd);
  754. }
  755.  
  756. closeoutput()
  757. {
  758.     if (verbose) {
  759.         fprintf(stderr, "%s:%s:closing output\n",
  760.             progname, parent ? "parent" : "child");
  761.         fflush(stderr);
  762.     }
  763.     if (outfile == NULL)
  764.         return;
  765.     if (close(outfd) < 0 && parent)
  766.         perror("close");
  767.     if (!rewindtape || !parent)
  768.         return;
  769.     if ((outfd = open(outfile, O_RDONLY)) >= 0)
  770.         close(outfd);
  771. }
  772.  
  773. reopenoutput()
  774. {
  775.     closeoutput();
  776.     fprintf(stderr, "%s:write error on the top of media\n", progname);
  777.     fprintf(stderr, "%s:remount and try again\n", progname);
  778.     return (openoutput());
  779.  
  780. }
  781.  
  782. reopeninput()
  783. {
  784.     closeinput();
  785.     fprintf(stderr, "%s:read error on top of media\n", progname);
  786.     fprintf(stderr, "%s:remount and try again\n", progname);
  787.     return (openinput());
  788.  
  789. }
  790.  
  791. askyes(msg)
  792.     char           *msg;
  793. {
  794.     char            s[BUFSIZ];
  795.     if (notty)
  796.         return -1;
  797.     for (;;) {
  798.         fprintf(stderr, "%s\n", msg);
  799.         fprintf(stderr, "OK? (y/n/q)");
  800.         fflush(stderr);
  801.         if (s != fgets(s, BUFSIZ - 1, ftty)) {
  802.             perror("control tty read");
  803.             xerror("job aborting");
  804.         }
  805.         if (*s == 'y' || *s == 'Y')
  806.             return 0;
  807.         if (*s == 'q' || *s == 'Q') {
  808.             if (parent > 0)    /* kill child */
  809.                 kill(parent, SIGKILL);
  810.             xerror("abort\n");
  811.         }
  812.     }
  813. }
  814.  
  815. openoutput()
  816. {
  817.     char            s[BUFSIZ];
  818.  
  819.     if (outfile == NULL) {
  820.         setsockbuf(1, SO_SNDBUF, osbs);
  821.         return 1;
  822.     }
  823.     sprintf(s, "%s:mount %d%s volume on %s\n", progname
  824.         ,volcount
  825.         ,volcount < 3 ? (volcount == 1 ? "st" : "nd")
  826.         : (volcount == 3 ? "rd" : "th"), outfile);
  827.     if (!notty && volcount > 1)
  828.         askyes(s);
  829.     for (;; askyes(s)) {
  830.         if (rewindtape) {
  831.             if ((outfd = open(outfile, O_RDWR)) > 0)
  832.                 close(outfd);
  833.             else {
  834.                 perror(outfile);
  835.                 if (!notty)
  836.                     continue;
  837.             }
  838.         }
  839.         if (outproc != NULL)
  840.             outfd = procopen(outproc, "w");
  841.         else
  842.             outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0777);
  843.         if (outfd < 0) {
  844.             perror(outfile);
  845.         } else {
  846.             return outfd;
  847.         }
  848.         if (notty)
  849.             xerror("job aborted\n");
  850.     }
  851. }
  852.  
  853. procopen(prog, rw)
  854.     char           *prog;
  855.     char           *rw;
  856. {
  857.     int             p[2];
  858.     int             pid;
  859.  
  860.     if (pipe(p) < 0)
  861.         return -1;
  862.     if ((pid = fork()) < 0)
  863.         return -1;
  864.     if (pid == 0) {
  865.         if (*rw == 'w') {
  866.             close(0);
  867.             dup(p[0]);
  868.             close(p[1]);
  869.             close(p[0]);
  870.             close(1);
  871.             open("/dev/null", O_WRONLY);
  872.         } else {
  873.             close(1);
  874.             dup(p[1]);
  875.             close(p[1]);
  876.             close(p[0]);
  877.             close(0);
  878.             open("/dev/null", 0);
  879.         }
  880.         execl("/bin/sh", "sh", "-c", prog, 0);
  881.         perror("exec");
  882.         exit(1);
  883.     }
  884.     if (*rw == 'w') {
  885.         close(p[0]);
  886.         setsockbuf(p[1], SO_SNDBUF, osbs);
  887.         return (p[1]);
  888.     } else {
  889.         close(p[1]);
  890.         setsockbuf(p[0], SO_RCVBUF, isbs);
  891.         return (p[0]);
  892.     }
  893. }
  894.  
  895. setup_pipe()
  896. {
  897.     int             p1[2], p2[2];
  898.     if (pipe(p1) < 0 || pipe(p2) < 0) {
  899.         perror("pipe");
  900.         xerror("");
  901.     }
  902.     if ((parent = fork()) < 0) {
  903.         perror("fork");
  904.         xerror("");
  905.     }
  906.     if (parent) {
  907.         if (verbose)
  908.             fprintf(stderr, "%s:forked child %d\n", progname, parent);
  909.         close(p1[0]);
  910.         pipeout = p1[1];
  911.         pipein = p2[0];
  912.         close(p2[1]);
  913.     } else {
  914.         static char     s[2] = {IN_OK, OUT_OK};
  915.         fclose(ftty);
  916.         if (!notty) {
  917.             freopen("/dev/tty", "w", stderr);
  918.         }
  919.         pipein = p1[0];
  920.         close(p1[1]);
  921.         close(p2[0]);
  922.         pipeout = p2[1];
  923.         if (write(pipeout, s, 2) != 2) {
  924.             perror("child cntrl pipe write");
  925.             xerror("");
  926.         }
  927.     }
  928. }
  929.  
  930. openinput()
  931. {
  932.     char            s[BUFSIZ];
  933.  
  934.     if (infile == NULL)  {
  935.         setsockbuf(0, SO_RCVBUF, isbs);
  936.         return (0);
  937.     }
  938.     sprintf(s, inproc == NULL ?
  939.          "%s:mount %d%s volume on %s\n" : "%s:%d%s invocation of '%s'\n"
  940.         ,progname
  941.         ,involcount
  942.         ,involcount < 3 ? (involcount == 1 ? "st" : "nd")
  943.         : (involcount == 3 ? "rd" : "th")
  944.         ,infile);
  945.     if (!notty && involcount > 1)
  946.         askyes(s);
  947.     for (;; askyes(s)) {
  948.         if (rewindtape) {
  949.             if ((infd = open(infile, O_RDONLY)) < 0) {
  950.                 perror(infile);
  951.                 if (notty)
  952.                     break;
  953.                 else
  954.                     continue;
  955.             }
  956.             close(infd);
  957.         }
  958.         if (inproc != NULL)
  959.             infd = procopen(inproc, "r");
  960.         else
  961.             infd = open(infile, O_RDONLY);
  962.         if (infd > 0)
  963.             break;
  964.         perror(infile);
  965.         if (notty)
  966.             break;
  967.     }
  968.     if (infd < 0)
  969.         xerror("job aborted\n");
  970.     return (infd);
  971. }
  972.  
  973. sizeparse(str)
  974. {
  975.     int i;
  976.     char *p;
  977.         char            buf[256];
  978.  
  979.     if((p=numparse(str, &i))!=NULL && *p=='\0')
  980.         return i;
  981.  
  982.  
  983.     (void) sprintf(buf, "%s:Unparsable number:%s\n", progname, str);
  984.     xerror(buf);
  985.     return (-1);        /* to shut up LINT */
  986. }
  987.  
  988. char *numparse(str, np)
  989.     char           *str;
  990.     int *np;
  991. {
  992.     register char  *s = str;
  993.     register int    i = 0;
  994.  
  995.     if (!isdigit(*s)) {
  996.         return NULL;
  997.     }
  998.     while (isdigit(*s))
  999.         i = i * 10 + *s++ - '0';
  1000.     if (*s != '\0') {
  1001.         switch (*s++) {
  1002.         case 'b':
  1003.         case 'B':
  1004.             i *= 512;
  1005.             break;
  1006.         case 'k':
  1007.         case 'K':
  1008.             i *= 1024;
  1009.             break;
  1010.         case 'm':
  1011.         case 'M':
  1012.             i *= 1024 * 1024;
  1013.             break;
  1014.         case '+':
  1015.             break;
  1016.         default:
  1017.             break;
  1018.         }
  1019.     }
  1020.     if (*s == '+') {
  1021.         int j;
  1022.         char *p;
  1023.  
  1024.         p=  numparse(s + 1, &j);
  1025.         *np= i+j;
  1026.         return s;
  1027.     }
  1028.  
  1029.     *np = i;
  1030.     return (s);
  1031. }
  1032.  
  1033. setpad(opt)
  1034.     char *opt;
  1035. {
  1036.     if(opt==NULL || *opt=='\0') {
  1037.         padmode= PAD_NORMAL;
  1038.         return 0;
  1039.     }
  1040.     do {
  1041.         if (strncmp(opt,"tar",3)==0) { 
  1042.             padmode= PAD_TAR;
  1043.             opt+=3;
  1044.             continue;
  1045.         } 
  1046.         if (isdigit(*opt)) {
  1047.             int i;
  1048.             if( (opt =  numparse(opt , &i)) !=NULL) {
  1049.                 padunit = i;
  1050.                 continue;
  1051.             }
  1052.         }
  1053.         else
  1054.         xerror("Unknown pad sub-opion\n");
  1055.     } while( *opt==',' && opt++);
  1056.     return 0;
  1057. }
  1058.  
  1059. xerror(errstr)
  1060.     char           *errstr;
  1061. {
  1062.     if (errstr != NULL)
  1063.         fputs(errstr, stderr);
  1064.     closeinput();
  1065.     closeoutput();
  1066.     close(pipein);
  1067.     close(pipeout);
  1068.     close(0);
  1069.     close(1);
  1070.     if (parent > 0) {
  1071.         kill(parent, SIGINT);
  1072.         if (ftty != NULL) {
  1073.             inbytes_total += inbytes;
  1074.             outbytes_total += outbytes;
  1075.             fprintf(stderr, "%d blks+%d bytes in\n",
  1076.                 inbytes_total / ibs, inbytes_total % ibs);
  1077.             fprintf(stderr, "%d blks+%d bytes out\n",
  1078.                 outbytes_total / obs, outbytes_total % obs);
  1079.         }
  1080.     }
  1081.     alarm(5);
  1082.     wait(0);
  1083.     exit(1);
  1084. }
  1085.  
  1086. argparse(argc, argv)
  1087.     int             argc;
  1088.     char           *argv[];
  1089. {
  1090.     register char  *pa, *po;
  1091.     register int    i;
  1092.  
  1093.     for (argc--, argv++; argc > 0; argc--, argv++) {
  1094.         for (i = 0; options[i].objptr != NULL; i++) {
  1095.             for (pa = *argv, po = options[i].name;
  1096.                  *pa && *po && *pa == *po;
  1097.                  pa++, po++);
  1098.             if (*po == '\0' && !isalpha(*pa))
  1099.                 break;
  1100.         }
  1101.         if (options[i].objptr == NULL) {
  1102.             usage("unknown option\n");
  1103.         }
  1104.         switch (options[i].attrib) {
  1105.         case NUM:
  1106.             if (*pa != '=')
  1107.                 xerror("illegal option format\n");
  1108.             *(int *) options[i].objptr = sizeparse(pa + 1);
  1109.             break;
  1110.         case STR:
  1111.             if (*pa != '=')
  1112.                 xerror("illegal option format\n");
  1113.             *(char **) options[i].objptr = pa + 1;
  1114.             break;
  1115.         case BOOL:
  1116.             {
  1117.                 int            *p;
  1118.                 p = (int *) options[i].objptr;
  1119.                 if (*pa == '\0')
  1120.                     *p = !*p;
  1121.                 else if (*pa == '+')
  1122.                     *p = 1;
  1123.                 else if (*pa == '-')
  1124.                     *p = 0;
  1125.                 else
  1126.                     xerror("illegal arg format\n");
  1127.             } break;
  1128.         case SPL:
  1129.             if (*pa == '=' )
  1130.                 pa++;
  1131.             else if ( *pa!='\0')
  1132.                 xerror("illegal option format\n");
  1133.             ((int (*)())options[i].objptr)(pa );
  1134.             break;
  1135.         }
  1136.     }
  1137. }
  1138.  
  1139. setsockbuf(fd, op, size)
  1140. {
  1141.        while (size > 1024 &&
  1142.           setsockopt(fd, SOL_SOCKET, op, &size, sizeof (size)) < 0)
  1143.           size = (size -1024) & ~ 1023 ;
  1144. }
  1145.  
  1146. ewrite(fd, buf, cnt, obs)
  1147.     register int    fd, obs;
  1148.     int             cnt;
  1149.     register char  *buf;
  1150. {
  1151.     register int    rest, n;
  1152.     static nEPIPE=0;
  1153.  
  1154.     for (rest = cnt; rest > 0; rest -= n, buf += n) {
  1155.         if (rest < obs) {
  1156.             if (padunit == 0)
  1157.                 obs = rest;
  1158.             else
  1159.                 obs = rest + padunit - 1 - ((rest - 1) % padunit);
  1160.         }
  1161.         if ((n = write(fd, buf, obs)) > 0) {
  1162.             nEPIPE =0;
  1163.             continue;
  1164.         }
  1165.         if (n == 0) {
  1166.             if ((n = write(fd, buf, obs)) > 0)
  1167.                 continue;
  1168.             if (n == 0) {
  1169.                 fprintf(stderr, "May be tape end\n");
  1170.                 return (-1);
  1171.             }
  1172.         }
  1173.         if (n < 0) {
  1174.             char            msg[BUFSIZ];
  1175.  
  1176.             sprintf(msg, "%s write %s", WHOAMI, OUTFILE);
  1177.             perror(msg);
  1178.             if (errno == EPIPE && ++nEPIPE < MAXEPIPE)
  1179.                 break;
  1180.             return -1;
  1181.         }
  1182.     }
  1183.     if (dofsync)
  1184.         fsync(fd);
  1185.     return cnt - rest;
  1186. }
  1187.  
  1188. get_token(t1, t2)
  1189. {
  1190.     char            c = 0;
  1191.     if (verbose) {
  1192.         fprintf(stderr, "%s:%s:waiting '%c'\n", progname,
  1193.             WHOAMI, t1);
  1194.         fflush(stderr);
  1195.     }
  1196.     if (read(pipein, &c, 1) != 1) {
  1197.         char            msg[BUFSIZ];
  1198.         if (t2 == -1) {
  1199.             if (verbose)
  1200.                 fprintf(stderr, "%s:%s:got eof\n", progname, WHOAMI);
  1201.             return -1;
  1202.  
  1203.         }
  1204.         sprintf(msg, "%s:%s:control pipe ", progname, WHOAMI);
  1205.         perror(msg);
  1206.         xerror("");
  1207.     } else if (verbose) {
  1208.         fprintf(stderr, "%s:%s:got %c\n", progname,
  1209.             WHOAMI, c);
  1210.     }
  1211.     if (c != t1 && c != t2) {
  1212.         fprintf(stderr, "%s:%s Syncronization error\n", progname, WHOAMI);
  1213.         xerror("");
  1214.     }
  1215.     return c & 0xFF;
  1216. }
  1217.  
  1218. get_int()
  1219. {
  1220.     char            c = 0;
  1221.     int i,n;
  1222.     char            msg[BUFSIZ];
  1223.  
  1224.     for (i=0;(n=read(pipein, &c, 1) )== 1;) {
  1225.         if(!isdigit(c))
  1226.             break;
  1227.         i=i*10 + c-'0';
  1228.     }
  1229.     if(n<0) {
  1230.         sprintf(msg, "%s:%s:control pipe read", progname, WHOAMI);
  1231.         perror(msg);
  1232.         xerror("");
  1233.     } else if (c!=' ') {
  1234.         fprintf(stderr, "%s:%s:number terminated with %c\n", progname,
  1235.             WHOAMI, c);
  1236.     } else if (verbose) {
  1237.         fprintf(stderr, "%s:%s:got %d\n", progname,
  1238.             WHOAMI, i);
  1239.     }
  1240.     return i;
  1241. }
  1242.  
  1243. put_token(t, ignoreerr)
  1244. {
  1245.     char            c;
  1246.     c = t;
  1247.     if (verbose) {
  1248.         fprintf(stderr, "%s:%s:write '%c' \n", progname,
  1249.             WHOAMI, c);
  1250.     }
  1251.     if (write(pipeout, &c, 1) != 1 && !ignoreerr) {
  1252.         char            buf[256];
  1253.         sprintf(buf, "%s:Control pipe write", WHOAMI);
  1254.         perror(buf);
  1255.         xerror("");
  1256.     }
  1257. }
  1258.  
  1259. put_int( num )
  1260. {
  1261.     char            buf[256];
  1262.     if (verbose) {
  1263.         fprintf(stderr, "%s:%s:write '%d' \n", progname,
  1264.             WHOAMI,  num );
  1265.     }
  1266.     sprintf(buf,"%d ", num );
  1267.     if (write(pipeout, buf, strlen(buf)) != strlen(buf)) {
  1268.         sprintf(buf, "%s:Control pipe write", WHOAMI);
  1269.         perror(buf);
  1270.         xerror("");
  1271.     }
  1272. }
  1273.  
  1274.  
  1275. #ifdef SYSV
  1276. #ifndef NBPG
  1277. #define NBPG 4096
  1278. #endif
  1279. char           *
  1280. valloc(sz)
  1281.     unsigned        sz;
  1282. {
  1283.     char           *p;
  1284.  
  1285.     if ((p = malloc(sz + NBPG)) == NULL)
  1286.         return NULL;
  1287.     return (char *) (~(NBPG - 1) & (NBPG + (long) p));
  1288. }
  1289. #endif
  1290. #if 0
  1291. termination protocol
  1292.  
  1293.  
  1294. CASE 1.
  1295.  
  1296. parent        child
  1297.  
  1298.     OUT_OK ->
  1299.     IN_OK  <-
  1300. read input
  1301. DETECT EOF
  1302.     EOF_APPEAR->
  1303.             write last-1 output
  1304.     OUT_OK <-
  1305. write last output
  1306. close input & output
  1307.             enter termination mode
  1308.     inbytes, outbytes <-
  1309. close pipe
  1310.             SIGPIPE & exit
  1311.  
  1312. CASE 2.
  1313.  
  1314. parent        child
  1315.  
  1316.     OUT_OK  <-
  1317.     IN_OK  ->
  1318. write last-1 output
  1319.         read input
  1320.         DETECT EOF
  1321.     DETECT_EOF <-
  1322.     OUT_OK ->
  1323.             write last output
  1324.     OUT_OK <-
  1325.             enter termination mode
  1326.     inbytes, outbytes <-
  1327. close input & output
  1328.     EOF_APPEAR->
  1329.             discarded
  1330. close pipe
  1331.             & exit
  1332.  
  1333.     
  1334. #endif
  1335. !End-Of-edd.c!
  1336. if test 22080 -ne "`wc -c < 'edd.c'`"
  1337. then
  1338.      echo shar: error transmitting "'edd.c'" '(should have been 22080 characters)'
  1339. fi
  1340. fi
  1341. #    End of shell archive
  1342.