io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "sam.h"
  10. #define NSYSFILE 3
  11. #define NOFILE 128
  12. void
  13. checkqid(File *f)
  14. {
  15. int i, w;
  16. File *g;
  17. w = whichmenu(f);
  18. for(i=1; i<file.nused; i++){
  19. g = file.filepptr[i];
  20. if(w == i)
  21. continue;
  22. if(f->dev==g->dev && f->qidpath==g->qidpath)
  23. warn_SS(Wdupfile, &f->name, &g->name);
  24. }
  25. }
  26. void
  27. writef(File *f)
  28. {
  29. Posn n;
  30. char *name;
  31. int i, samename, newfile;
  32. ulong dev;
  33. uvlong qid;
  34. long mtime, appendonly, length;
  35. newfile = 0;
  36. samename = Strcmp(&genstr, &f->name) == 0;
  37. name = Strtoc(&f->name);
  38. i = statfile(name, &dev, &qid, &mtime, 0, 0);
  39. if(i == -1)
  40. newfile++;
  41. else if(samename &&
  42. (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
  43. f->dev = dev;
  44. f->qidpath = qid;
  45. f->mtime = mtime;
  46. warn_S(Wdate, &genstr);
  47. return;
  48. }
  49. if(genc)
  50. free(genc);
  51. genc = Strtoc(&genstr);
  52. if((io=create(genc, 1, 0666L)) < 0)
  53. error_r(Ecreate, genc);
  54. dprint("%s: ", genc);
  55. if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
  56. error(Eappend);
  57. n = writeio(f);
  58. if(f->name.s[0]==0 || samename){
  59. if(addr.r.p1==0 && addr.r.p2==f->Buffer.nc)
  60. f->cleanseq = f->seq;
  61. state(f, f->cleanseq==f->seq? Clean : Dirty);
  62. }
  63. if(newfile)
  64. dprint("(new file) ");
  65. if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
  66. warn(Wnotnewline);
  67. closeio(n);
  68. if(f->name.s[0]==0 || samename){
  69. if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
  70. f->dev = dev;
  71. f->qidpath = qid;
  72. f->mtime = mtime;
  73. checkqid(f);
  74. }
  75. }
  76. }
  77. Posn
  78. readio(File *f, int *nulls, int setdate, int toterm)
  79. {
  80. int n, b, w;
  81. Rune *r;
  82. Posn nt;
  83. Posn p = addr.r.p2;
  84. ulong dev;
  85. uvlong qid;
  86. long mtime;
  87. char buf[BLOCKSIZE+1], *s;
  88. *nulls = FALSE;
  89. b = 0;
  90. if(f->unread){
  91. nt = bufload(&f->Buffer, 0, io, nulls);
  92. if(toterm)
  93. raspload(f);
  94. }else
  95. for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
  96. n += b;
  97. b = 0;
  98. r = genbuf;
  99. s = buf;
  100. while(n > 0){
  101. if((*r = *(uchar*)s) < Runeself){
  102. if(*r)
  103. r++;
  104. else
  105. *nulls = TRUE;
  106. --n;
  107. s++;
  108. continue;
  109. }
  110. if(fullrune(s, n)){
  111. w = chartorune(r, s);
  112. if(*r)
  113. r++;
  114. else
  115. *nulls = TRUE;
  116. n -= w;
  117. s += w;
  118. continue;
  119. }
  120. b = n;
  121. memmove(buf, s, b);
  122. break;
  123. }
  124. loginsert(f, p, genbuf, r-genbuf);
  125. }
  126. if(b)
  127. *nulls = TRUE;
  128. if(*nulls)
  129. warn(Wnulls);
  130. if(setdate){
  131. if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
  132. f->dev = dev;
  133. f->qidpath = qid;
  134. f->mtime = mtime;
  135. checkqid(f);
  136. }
  137. }
  138. return nt;
  139. }
  140. Posn
  141. writeio(File *f)
  142. {
  143. int m, n;
  144. Posn p = addr.r.p1;
  145. char *c;
  146. while(p < addr.r.p2){
  147. if(addr.r.p2-p>BLOCKSIZE)
  148. n = BLOCKSIZE;
  149. else
  150. n = addr.r.p2-p;
  151. bufread(&f->Buffer, p, genbuf, n);
  152. c = Strtoc(tmprstr(genbuf, n));
  153. m = strlen(c);
  154. if(Write(io, c, m) != m){
  155. free(c);
  156. if(p > 0)
  157. p += n;
  158. break;
  159. }
  160. free(c);
  161. p += n;
  162. }
  163. return p-addr.r.p1;
  164. }
  165. void
  166. closeio(Posn p)
  167. {
  168. close(io);
  169. io = 0;
  170. if(p >= 0)
  171. dprint("#%lud\n", p);
  172. }
  173. int remotefd0 = 0;
  174. int remotefd1 = 1;
  175. void
  176. bootterm(char *machine, char **argv)
  177. {
  178. int ph2t[2], pt2h[2];
  179. if(machine){
  180. dup(remotefd0, 0);
  181. dup(remotefd1, 1);
  182. close(remotefd0);
  183. close(remotefd1);
  184. argv[0] = "samterm";
  185. exec(samterm, argv);
  186. fprint(2, "can't exec: ");
  187. perror(samterm);
  188. _exits("damn");
  189. }
  190. if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
  191. panic("pipe");
  192. switch(fork()){
  193. case 0:
  194. dup(ph2t[0], 0);
  195. dup(pt2h[1], 1);
  196. close(ph2t[0]);
  197. close(ph2t[1]);
  198. close(pt2h[0]);
  199. close(pt2h[1]);
  200. argv[0] = "samterm";
  201. exec(samterm, argv);
  202. fprint(2, "can't exec: ");
  203. perror(samterm);
  204. _exits("damn");
  205. case -1:
  206. panic("can't fork samterm");
  207. }
  208. dup(pt2h[0], 0);
  209. dup(ph2t[1], 1);
  210. close(ph2t[0]);
  211. close(ph2t[1]);
  212. close(pt2h[0]);
  213. close(pt2h[1]);
  214. }
  215. void
  216. connectto(char *machine, char **argv)
  217. {
  218. int p1[2], p2[2];
  219. char **av;
  220. int ac;
  221. // count args
  222. for(av = argv; *av; av++)
  223. ;
  224. av = malloc(sizeof(char*)*((av-argv) + 5));
  225. if(av == nil){
  226. dprint("out of memory\n");
  227. exits("fork/exec");
  228. }
  229. ac = 0;
  230. av[ac++] = RX;
  231. av[ac++] = machine;
  232. av[ac++] = rsamname;
  233. av[ac++] = "-R";
  234. while(*argv)
  235. av[ac++] = *argv++;
  236. av[ac] = 0;
  237. if(pipe(p1)<0 || pipe(p2)<0){
  238. dprint("can't pipe\n");
  239. exits("pipe");
  240. }
  241. remotefd0 = p1[0];
  242. remotefd1 = p2[1];
  243. switch(fork()){
  244. case 0:
  245. dup(p2[0], 0);
  246. dup(p1[1], 1);
  247. close(p1[0]);
  248. close(p1[1]);
  249. close(p2[0]);
  250. close(p2[1]);
  251. exec(RXPATH, av);
  252. dprint("can't exec %s\n", RXPATH);
  253. exits("exec");
  254. case -1:
  255. dprint("can't fork\n");
  256. exits("fork");
  257. }
  258. free(av);
  259. close(p1[1]);
  260. close(p2[0]);
  261. }
  262. void
  263. startup(char *machine, int Rflag, char **argv, char **files)
  264. {
  265. if(machine)
  266. connectto(machine, files);
  267. if(!Rflag)
  268. bootterm(machine, argv);
  269. downloaded = 1;
  270. outTs(Hversion, VERSION);
  271. }