io.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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, char **end)
  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. *end = 0;
  178. exec(samterm, argv);
  179. fprint(2, "can't exec: ");
  180. perror(samterm);
  181. _exits("damn");
  182. }
  183. if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
  184. panic("pipe");
  185. switch(fork()){
  186. case 0:
  187. dup(ph2t[0], 0);
  188. dup(pt2h[1], 1);
  189. close(ph2t[0]);
  190. close(ph2t[1]);
  191. close(pt2h[0]);
  192. close(pt2h[1]);
  193. argv[0] = "samterm";
  194. *end = 0;
  195. exec(samterm, argv);
  196. fprint(2, "can't exec: ");
  197. perror(samterm);
  198. _exits("damn");
  199. case -1:
  200. panic("can't fork samterm");
  201. }
  202. dup(pt2h[0], 0);
  203. dup(ph2t[1], 1);
  204. close(ph2t[0]);
  205. close(ph2t[1]);
  206. close(pt2h[0]);
  207. close(pt2h[1]);
  208. }
  209. void
  210. connectto(char *machine)
  211. {
  212. int p1[2], p2[2];
  213. if(pipe(p1)<0 || pipe(p2)<0){
  214. dprint("can't pipe\n");
  215. exits("pipe");
  216. }
  217. remotefd0 = p1[0];
  218. remotefd1 = p2[1];
  219. switch(fork()){
  220. case 0:
  221. dup(p2[0], 0);
  222. dup(p1[1], 1);
  223. close(p1[0]);
  224. close(p1[1]);
  225. close(p2[0]);
  226. close(p2[1]);
  227. execl(RXPATH, RX, machine, rsamname, "-R", (char*)0);
  228. dprint("can't exec %s\n", RXPATH);
  229. exits("exec");
  230. case -1:
  231. dprint("can't fork\n");
  232. exits("fork");
  233. }
  234. close(p1[1]);
  235. close(p2[0]);
  236. }
  237. void
  238. startup(char *machine, int Rflag, char **argv, char **end)
  239. {
  240. if(machine)
  241. connectto(machine);
  242. if(!Rflag)
  243. bootterm(machine, argv, end);
  244. downloaded = 1;
  245. outTs(Hversion, VERSION);
  246. }