io.c 4.6 KB

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