comparison contrib/hgsh/hgsh.c @ 2602:9cbeef33eaa3

contrib/hgsh: make to work with remote clone over ssh.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Wed, 12 Jul 2006 15:44:51 -0700
parents dbbe7f72d15a
children 59ddd43f609f
comparison
equal deleted inserted replaced
2601:00fc88b0b256 2602:9cbeef33eaa3
242 execv(hg_shell, nargv); 242 execv(hg_shell, nargv);
243 perror(hg_shell); 243 perror(hg_shell);
244 exit(EX_OSFILE); 244 exit(EX_OSFILE);
245 } 245 }
246 246
247 enum cmdline {
248 hg_init,
249 hg_serve,
250 };
251
252
247 /* 253 /*
248 * paranoid wrapper, runs hg executable in server mode. 254 * paranoid wrapper, runs hg executable in server mode.
249 */ 255 */
250 static void serve_data(int argc, char **argv) 256 static void serve_data(int argc, char **argv)
251 { 257 {
252 char *hg_root = HG_ROOT; 258 char *hg_root = HG_ROOT;
253 char *repo, *abspath; 259 char *repo, *repo_root;
260 enum cmdline cmd;
254 char *nargv[6]; 261 char *nargv[6];
255 struct stat st; 262 struct stat st;
256 size_t repolen; 263 size_t repolen;
257 int i; 264 int i;
258 265
273 280
274 if (strcmp(argv[1], "-c") != 0) { 281 if (strcmp(argv[1], "-c") != 0) {
275 goto badargs; 282 goto badargs;
276 } 283 }
277 284
278 if (sscanf(argv[2], "hg -R %as serve --stdio", &repo) != 1) { 285 if (sscanf(argv[2], "hg init %as", &repo) == 1) {
286 cmd = hg_init;
287 }
288 else if (sscanf(argv[2], "hg -R %as serve --stdio", &repo) == 1) {
289 cmd = hg_serve;
290 } else {
279 goto badargs; 291 goto badargs;
280 } 292 }
281 293
282 repolen = repo ? strlen(repo) : 0; 294 repolen = repo ? strlen(repo) : 0;
283 295
284 if (repolen == 0) { 296 if (repolen == 0) {
285 goto badargs; 297 goto badargs;
286 } 298 }
287 299
288 if (hg_root) { 300 if (hg_root) {
289 if (asprintf(&abspath, "%s/%s/.hg/data", hg_root, repo) == -1) { 301 if (asprintf(&repo_root, "%s/%s/", hg_root, repo) == -1) {
290 goto badargs; 302 goto badargs;
291 } 303 }
292 304
293 /* 305 /*
294 * attempt to stop break out from inside the repository tree. could 306 * attempt to stop break out from inside the repository tree. could
295 * do something more clever here, because e.g. we could traverse a 307 * do something more clever here, because e.g. we could traverse a
296 * symlink that looks safe, but really breaks us out of tree. 308 * symlink that looks safe, but really breaks us out of tree.
297 */ 309 */
298 310
299 if (strstr(abspath, "/../") != NULL) { 311 if (strstr(repo_root, "/../") != NULL) {
300 goto badargs; 312 goto badargs;
301 } 313 }
302 314
303 /* verify that we really are looking at valid repo. */ 315 /* only hg init expects no repo. */
304 316
305 if (stat(abspath, &st) == -1) { 317 if (cmd != hg_init) {
306 perror(repo); 318 char *abs_path;
307 exit(EX_DATAERR); 319
308 } 320 if (asprintf(&abs_path, "%s.hg/data", repo_root) == -1) {
321 goto badargs;
322 }
323
324 /* verify that we really are looking at valid repo. */
325
326 if (stat(abs_path, &st) == -1) {
327 perror(repo);
328 exit(EX_DATAERR);
329 }
330 }
309 331
310 if (chdir(hg_root) == -1) { 332 if (chdir(hg_root) == -1) {
311 perror(hg_root); 333 perror(hg_root);
312 exit(EX_SOFTWARE); 334 exit(EX_SOFTWARE);
313 } 335 }
314 } 336 }
315 337
316 i = 0; 338 i = 0;
317 nargv[i++] = HG; 339
318 nargv[i++] = "-R"; 340 switch (cmd) {
319 nargv[i++] = repo; 341 case hg_serve:
320 nargv[i++] = "serve"; 342 nargv[i++] = HG;
321 nargv[i++] = "--stdio"; 343 nargv[i++] = "-R";
344 nargv[i++] = repo;
345 nargv[i++] = "serve";
346 nargv[i++] = "--stdio";
347 break;
348 case hg_init:
349 nargv[i++] = HG;
350 nargv[i++] = "init";
351 nargv[i++] = repo;
352 break;
353 }
354
322 nargv[i] = NULL; 355 nargv[i] = NULL;
323 356
324 if (debug) { 357 if (debug) {
325 print_cmdline(i, nargv); 358 print_cmdline(i, nargv);
326 } 359 }