contrib/chg/chg.c
changeset 28535 aa082a8125da
parent 28516 3bf2892f685f
child 28555 1435a8e9b5fe
equal deleted inserted replaced
28534:293adbaa14a7 28535:aa082a8125da
   442 	close(pipefds[0]);
   442 	close(pipefds[0]);
   443 	close(pipefds[1]);
   443 	close(pipefds[1]);
   444 	abortmsg("failed to prepare pager (errno = %d)", errno);
   444 	abortmsg("failed to prepare pager (errno = %d)", errno);
   445 }
   445 }
   446 
   446 
   447 /* Run instructions sent from the server like unlink and set redirect path */
   447 /* Run instructions sent from the server like unlink and set redirect path
   448 static void runinstructions(struct cmdserveropts *opts, const char **insts)
   448  * Return 1 if reconnect is needed, otherwise 0 */
   449 {
   449 static int runinstructions(struct cmdserveropts *opts, const char **insts)
       
   450 {
       
   451 	int needreconnect = 0;
       
   452 	if (!insts)
       
   453 		return needreconnect;
       
   454 
   450 	assert(insts);
   455 	assert(insts);
   451 	opts->redirectsockname[0] = '\0';
   456 	opts->redirectsockname[0] = '\0';
   452 	const char **pinst;
   457 	const char **pinst;
   453 	for (pinst = insts; *pinst; pinst++) {
   458 	for (pinst = insts; *pinst; pinst++) {
   454 		debugmsg("instruction: %s", *pinst);
   459 		debugmsg("instruction: %s", *pinst);
   458 			int r = snprintf(opts->redirectsockname,
   463 			int r = snprintf(opts->redirectsockname,
   459 					 sizeof(opts->redirectsockname),
   464 					 sizeof(opts->redirectsockname),
   460 					 "%s", *pinst + 9);
   465 					 "%s", *pinst + 9);
   461 			if (r < 0 || r >= (int)sizeof(opts->redirectsockname))
   466 			if (r < 0 || r >= (int)sizeof(opts->redirectsockname))
   462 				abortmsg("redirect path is too long (%d)", r);
   467 				abortmsg("redirect path is too long (%d)", r);
       
   468 			needreconnect = 1;
   463 		} else if (strncmp(*pinst, "exit ", 5) == 0) {
   469 		} else if (strncmp(*pinst, "exit ", 5) == 0) {
   464 			int n = 0;
   470 			int n = 0;
   465 			if (sscanf(*pinst + 5, "%d", &n) != 1)
   471 			if (sscanf(*pinst + 5, "%d", &n) != 1)
   466 				abortmsg("cannot read the exit code");
   472 				abortmsg("cannot read the exit code");
   467 			exit(n);
   473 			exit(n);
       
   474 		} else if (strcmp(*pinst, "reconnect") == 0) {
       
   475 			needreconnect = 1;
   468 		} else {
   476 		} else {
   469 			abortmsg("unknown instruction: %s", *pinst);
   477 			abortmsg("unknown instruction: %s", *pinst);
   470 		}
   478 		}
   471 	}
   479 	}
       
   480 	return needreconnect;
   472 }
   481 }
   473 
   482 
   474 /*
   483 /*
   475  * Test whether the command is unsupported or not. This is not designed to
   484  * Test whether the command is unsupported or not. This is not designed to
   476  * cover all cases. But it's fast, does not depend on the server and does
   485  * cover all cases. But it's fast, does not depend on the server and does
   540 		hgc = connectcmdserver(&opts);
   549 		hgc = connectcmdserver(&opts);
   541 		if (!hgc)
   550 		if (!hgc)
   542 			abortmsg("cannot open hg client");
   551 			abortmsg("cannot open hg client");
   543 		hgc_setenv(hgc, envp);
   552 		hgc_setenv(hgc, envp);
   544 		const char **insts = hgc_validate(hgc, argv + 1, argc - 1);
   553 		const char **insts = hgc_validate(hgc, argv + 1, argc - 1);
   545 		if (insts == NULL)
   554 		int needreconnect = runinstructions(&opts, insts);
       
   555 		free(insts);
       
   556 		if (!needreconnect)
   546 			break;
   557 			break;
   547 		runinstructions(&opts, insts);
       
   548 		free(insts);
       
   549 		hgc_close(hgc);
   558 		hgc_close(hgc);
   550 		if (++retry > 10)
   559 		if (++retry > 10)
   551 			abortmsg("too many redirections.\n"
   560 			abortmsg("too many redirections.\n"
   552 				 "Please make sure %s is not a wrapper which "
   561 				 "Please make sure %s is not a wrapper which "
   553 				 "changes sensitive environment variables "
   562 				 "changes sensitive environment variables "