changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > ventivac / appl/cmd/vacget.b

changeset 122: 84abb5444a76
parent: c6c061169cb7
child: 07b5d02499fd
author: Mechiel Lukkien <mechiel@ueber.net>
date: Fri, 17 Aug 2007 22:28:53 +0200
permissions: -rw-r--r--
description: remove dflag from vac library interface. doesn't belong there anymore.
1 implement Vacget;
2 
3 include "sys.m";
4  sys: Sys;
5 include "draw.m";
6 include "bufio.m";
7  bufio: Bufio;
8  Iobuf: import bufio;
9 include "arg.m";
10 include "string.m";
11 include "venti.m";
12 include "vac.m";
13 
14 str: String;
15 venti: Venti;
16 vac: Vac;
17 
18 print, sprint, fprint, fildes: import sys;
19 Score, Session: import venti;
20 Direntry, Modeperm, Modeappend, Modeexcl, Modedir, Modesnapshot, Vacdir, Vacfile: import vac;
21 
22 Vacget: module {
23  init: fn(nil: ref Draw->Context, args: list of string);
24 };
25 
26 addr := "net!$venti!venti";
27 Dflag := vflag := pflag := tflag := 0;
28 session: ref Session;
29 
30 init(nil: ref Draw->Context, args: list of string)
31 {
32  sys = load Sys Sys->PATH;
33  bufio = load Bufio Bufio->PATH;
34  arg := load Arg Arg->PATH;
35  str = load String String->PATH;
36  venti = load Venti Venti->PATH;
37  vac = load Vac Vac->PATH;
38 
39  venti->init();
40  vac->init();
41 
42  arg->init(args);
43  arg->setusage(sprint("%s [-Dptv] [-a addr] vacfile", arg->progname()));
44  while((c := arg->opt()) != 0)
45  case c {
46  'a' => addr = arg->earg();
47  'D' => Dflag++;
48  'p' => pflag++;
49  't' => tflag++;
50  'v' => vflag++;
51  * => arg->usage();
52  }
53  args = arg->argv();
54  if(len args != 1)
55  arg->usage();
56 
57  (nil, score, serr) := vac->readscore(hd args);
58  if(serr != nil)
59  error("reading score: "+serr);
60  say("have score");
61 
62  (cok, conn) := sys->dial(addr, nil);
63  if(cok < 0)
64  error(sprint("dialing %s: %r", addr));
65  say("have connection");
66 
67  fd := conn.dfd;
68  session = Session.new(fd);
69  if(session == nil)
70  error(sprint("handshake: %r"));
71  say("have handshake");
72 
73  (vd, nil, err) := vac->vdroot(session, *score);
74  if(err != nil)
75  error(err);
76 
77  say("starting walk");
78  walk(".", vd);
79 }
80 
81 create(path: string, omode: int, de: ref Direntry): ref Sys->FD
82 {
83  perm := Sys->DMDIR | Sys->DMAPPEND | Sys->DMEXCL | Sys->DMTMP;
84  perm &= de.emode;
85  perm |= 8r666;
86  if(de.emode & Sys->DMDIR)
87  perm |= 8r777;
88  fd := sys->create(path, omode, perm);
89  if(fd == nil)
90  return nil;
91  if(pflag) {
92  d := sys->nulldir;
93  d.uid = de.uid;
94  d.gid = de.gid;
95  d.mode = de.emode;
96  if(sys->fwstat(fd, d) != 0) {
97  fprint(fildes(2), "fwstat %s for uid/gid/mode: %r", path);
98  d.uid = d.gid = "";
99  sys->fwstat(fd, d);
100  }
101  }
102  return fd;
103 }
104 
105 walk(path: string, vd: ref Vacdir)
106 {
107  say("start of walk: "+path);
108  for(;;) {
109  (n, de) := vd.readdir();
110  if(n < 0)
111  error(sprint("reading direntry in %s: %r", path));
112  if(n == 0)
113  break;
114  say("walk: have direntry, elem="+de.elem);
115  newpath := path+"/"+de.elem;
116  (e, me) := vd.open(de);
117  if(e == nil)
118  error(sprint("reading entry for %s: %r", newpath));
119 
120  oflags := de.mode&~(Modeperm|Modeappend|Modeexcl|Modedir|Modesnapshot);
121  if(oflags)
122  fprint(fildes(2), "%s: not all bits in mode can be set: 0x%x", newpath, oflags);
123 
124  if(tflag || vflag)
125  fprint(fildes(2), "%s\n", newpath);
126 
127  if(me != nil) {
128  if(!tflag)
129  create(newpath, Sys->OREAD, de);
130  # ignore error, possibly for already existing dir.
131  # if creating really failed, writing files in the dir will fail later on.
132  walk(newpath, Vacdir.new(session, e, me));
133  } else {
134  if(tflag)
135  continue;
136  say("writing file");
137  fd := create(newpath, sys->OWRITE, de);
138  if(fd == nil)
139  error(sprint("creating %s: %r", newpath));
140  bio := bufio->fopen(fd, bufio->OWRITE);
141  if(bio == nil)
142  error(sprint("bufio fopen %s: %r", newpath));
143 
144  buf := array[sys->ATOMICIO] of byte;
145  vf := Vacfile.new(session, e);
146  for(;;) {
147  rn := vf.read(buf, len buf);
148  if(rn == 0)
149  break;
150  if(rn < 0)
151  error(sprint("reading vac %s: %r", newpath));
152  wn := bio.write(buf, rn);
153  if(wn != rn)
154  error(sprint("writing local %s: %r", newpath));
155  }
156  bok := bio.flush();
157  bio.close();
158  if(bok == bufio->ERROR || bok == bufio->EOF)
159  error(sprint("bufio close: %r"));
160 
161  if(pflag) {
162  d := sys->nulldir;
163  d.mtime = de.mtime;
164  if(sys->fwstat(fd, d) < 0)
165  fprint(fildes(2), "fwstat %s for mtime: %r", newpath);
166  }
167  fd = nil;
168  }
169  }
170 }
171 
172 error(s: string)
173 {
174  fprint(fildes(2), "%s\n", s);
175  raise "fail:"+s;
176 }
177 
178 say(s: string)
179 {
180  if(Dflag)
181  fprint(fildes(2), "%s\n", s);
182 }