##// END OF EJS Templates
convert: raise Abort instead of NoRepo when CVS pserver auth fails....
Brendan Cully -
r5182:7e05bdee default
parent child Browse files
Show More
@@ -1,263 +1,263 b''
1 1 # CVS conversion code inspired by hg-cvs-import and git-cvsimport
2 2
3 3 import os, locale, re, socket
4 4 from mercurial import util
5 5
6 6 from common import NoRepo, commit, converter_source
7 7
8 8 class convert_cvs(converter_source):
9 9 def __init__(self, ui, path, rev=None):
10 10 super(convert_cvs, self).__init__(ui, path, rev=rev)
11 11
12 12 cvs = os.path.join(path, "CVS")
13 13 if not os.path.exists(cvs):
14 14 raise NoRepo("couldn't open CVS repo %s" % path)
15 15
16 16 self.changeset = {}
17 17 self.files = {}
18 18 self.tags = {}
19 19 self.lastbranch = {}
20 20 self.parent = {}
21 21 self.socket = None
22 22 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1]
23 23 self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1]
24 24 self.encoding = locale.getpreferredencoding()
25 25 self._parse()
26 26 self._connect()
27 27
28 28 def _parse(self):
29 29 if self.changeset:
30 30 return
31 31
32 32 maxrev = 0
33 33 cmd = 'cvsps -A -u --cvs-direct -q'
34 34 if self.rev:
35 35 # TODO: handle tags
36 36 try:
37 37 # patchset number?
38 38 maxrev = int(self.rev)
39 39 except ValueError:
40 40 try:
41 41 # date
42 42 util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S'])
43 43 cmd = "%s -d '1970/01/01 00:00:01' -d '%s'" % (cmd, self.rev)
44 44 except util.Abort:
45 45 raise util.Abort('revision %s is not a patchset number or date' % self.rev)
46 46
47 47 d = os.getcwd()
48 48 try:
49 49 os.chdir(self.path)
50 50 id = None
51 51 state = 0
52 52 for l in os.popen(cmd):
53 53 if state == 0: # header
54 54 if l.startswith("PatchSet"):
55 55 id = l[9:-2]
56 56 if maxrev and int(id) > maxrev:
57 57 state = 3
58 58 elif l.startswith("Date"):
59 59 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
60 60 date = util.datestr(date)
61 61 elif l.startswith("Branch"):
62 62 branch = l[8:-1]
63 63 self.parent[id] = self.lastbranch.get(branch, 'bad')
64 64 self.lastbranch[branch] = id
65 65 elif l.startswith("Ancestor branch"):
66 66 ancestor = l[17:-1]
67 67 self.parent[id] = self.lastbranch[ancestor]
68 68 elif l.startswith("Author"):
69 69 author = self.recode(l[8:-1])
70 70 elif l.startswith("Tag:") or l.startswith("Tags:"):
71 71 t = l[l.index(':')+1:]
72 72 t = [ut.strip() for ut in t.split(',')]
73 73 if (len(t) > 1) or (t[0] and (t[0] != "(none)")):
74 74 self.tags.update(dict.fromkeys(t, id))
75 75 elif l.startswith("Log:"):
76 76 state = 1
77 77 log = ""
78 78 elif state == 1: # log
79 79 if l == "Members: \n":
80 80 files = {}
81 81 log = self.recode(log[:-1])
82 82 state = 2
83 83 else:
84 84 log += l
85 85 elif state == 2:
86 86 if l == "\n": #
87 87 state = 0
88 88 p = [self.parent[id]]
89 89 if id == "1":
90 90 p = []
91 91 if branch == "HEAD":
92 92 branch = ""
93 93 c = commit(author=author, date=date, parents=p,
94 94 desc=log, branch=branch)
95 95 self.changeset[id] = c
96 96 self.files[id] = files
97 97 else:
98 98 colon = l.rfind(':')
99 99 file = l[1:colon]
100 100 rev = l[colon+1:-2]
101 101 rev = rev.split("->")[1]
102 102 files[file] = rev
103 103 elif state == 3:
104 104 continue
105 105
106 106 self.heads = self.lastbranch.values()
107 107 finally:
108 108 os.chdir(d)
109 109
110 110 def _connect(self):
111 111 root = self.cvsroot
112 112 conntype = None
113 113 user, host = None, None
114 114 cmd = ['cvs', 'server']
115 115
116 116 self.ui.status("connecting to %s\n" % root)
117 117
118 118 if root.startswith(":pserver:"):
119 119 root = root[9:]
120 120 m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
121 121 root)
122 122 if m:
123 123 conntype = "pserver"
124 124 user, passw, serv, port, root = m.groups()
125 125 if not user:
126 126 user = "anonymous"
127 127 if not port:
128 128 port = 2401
129 129 else:
130 130 port = int(port)
131 131 format0 = ":pserver:%s@%s:%s" % (user, serv, root)
132 132 format1 = ":pserver:%s@%s:%d%s" % (user, serv, port, root)
133 133
134 134 if not passw:
135 135 passw = "A"
136 136 pf = open(os.path.join(os.environ["HOME"], ".cvspass"))
137 137 for line in pf.read().splitlines():
138 138 part1, part2 = line.split(' ', 1)
139 139 if part1 == '/1':
140 140 # /1 :pserver:user@example.com:2401/cvsroot/foo Ah<Z
141 141 part1, part2 = part2.split(' ', 1)
142 142 format = format1
143 143 else:
144 144 # :pserver:user@example.com:/cvsroot/foo Ah<Z
145 145 format = format0
146 146 if part1 == format:
147 147 passw = part2
148 148 break
149 149 pf.close()
150 150
151 151 sck = socket.socket()
152 152 sck.connect((serv, port))
153 153 sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw,
154 154 "END AUTH REQUEST", ""]))
155 155 if sck.recv(128) != "I LOVE YOU\n":
156 raise NoRepo("CVS pserver authentication failed")
156 raise util.Abort("CVS pserver authentication failed")
157 157
158 158 self.writep = self.readp = sck.makefile('r+')
159 159
160 160 if not conntype and root.startswith(":local:"):
161 161 conntype = "local"
162 162 root = root[7:]
163 163
164 164 if not conntype:
165 165 # :ext:user@host/home/user/path/to/cvsroot
166 166 if root.startswith(":ext:"):
167 167 root = root[5:]
168 168 m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root)
169 169 if not m:
170 170 conntype = "local"
171 171 else:
172 172 conntype = "rsh"
173 173 user, host, root = m.group(1), m.group(2), m.group(3)
174 174
175 175 if conntype != "pserver":
176 176 if conntype == "rsh":
177 177 rsh = os.environ.get("CVS_RSH" or "rsh")
178 178 if user:
179 179 cmd = [rsh, '-l', user, host] + cmd
180 180 else:
181 181 cmd = [rsh, host] + cmd
182 182
183 183 self.writep, self.readp = os.popen2(cmd)
184 184
185 185 self.realroot = root
186 186
187 187 self.writep.write("Root %s\n" % root)
188 188 self.writep.write("Valid-responses ok error Valid-requests Mode"
189 189 " M Mbinary E Checked-in Created Updated"
190 190 " Merged Removed\n")
191 191 self.writep.write("valid-requests\n")
192 192 self.writep.flush()
193 193 r = self.readp.readline()
194 194 if not r.startswith("Valid-requests"):
195 195 raise util.Abort("server sucks")
196 196 if "UseUnchanged" in r:
197 197 self.writep.write("UseUnchanged\n")
198 198 self.writep.flush()
199 199 r = self.readp.readline()
200 200
201 201 def getheads(self):
202 202 return self.heads
203 203
204 204 def _getfile(self, name, rev):
205 205 if rev.endswith("(DEAD)"):
206 206 raise IOError
207 207
208 208 args = ("-N -P -kk -r %s --" % rev).split()
209 209 args.append(os.path.join(self.cvsrepo, name))
210 210 for x in args:
211 211 self.writep.write("Argument %s\n" % x)
212 212 self.writep.write("Directory .\n%s\nco\n" % self.realroot)
213 213 self.writep.flush()
214 214
215 215 data = ""
216 216 while 1:
217 217 line = self.readp.readline()
218 218 if line.startswith("Created ") or line.startswith("Updated "):
219 219 self.readp.readline() # path
220 220 self.readp.readline() # entries
221 221 mode = self.readp.readline()[:-1]
222 222 count = int(self.readp.readline()[:-1])
223 223 data = self.readp.read(count)
224 224 elif line.startswith(" "):
225 225 data += line[1:]
226 226 elif line.startswith("M "):
227 227 pass
228 228 elif line.startswith("Mbinary "):
229 229 count = int(self.readp.readline()[:-1])
230 230 data = self.readp.read(count)
231 231 else:
232 232 if line == "ok\n":
233 233 return (data, "x" in mode and "x" or "")
234 234 elif line.startswith("E "):
235 235 self.ui.warn("cvs server: %s\n" % line[2:])
236 236 elif line.startswith("Remove"):
237 237 l = self.readp.readline()
238 238 l = self.readp.readline()
239 239 if l != "ok\n":
240 240 raise util.Abort("unknown CVS response: %s" % l)
241 241 else:
242 242 raise util.Abort("unknown CVS response: %s" % line)
243 243
244 244 def getfile(self, file, rev):
245 245 data, mode = self._getfile(file, rev)
246 246 self.modecache[(file, rev)] = mode
247 247 return data
248 248
249 249 def getmode(self, file, rev):
250 250 return self.modecache[(file, rev)]
251 251
252 252 def getchanges(self, rev):
253 253 self.modecache = {}
254 254 files = self.files[rev]
255 255 cl = files.items()
256 256 cl.sort()
257 257 return (cl, {})
258 258
259 259 def getcommit(self, rev):
260 260 return self.changeset[rev]
261 261
262 262 def gettags(self):
263 263 return self.tags
General Comments 0
You need to be logged in to leave comments. Login now