aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rtty.c75
1 files changed, 19 insertions, 56 deletions
diff --git a/rtty.c b/rtty.c
index f5df4ac..50b79e8 100644
--- a/rtty.c
+++ b/rtty.c
@@ -37,14 +37,12 @@ main(int argc, char *argv[])
signal(SIGQUIT, killall);
signal(SIGCHLD, killall);
- /* Create named pipes. */
sprintf(in, "/var/tmp/rtty.in.%d", getpid());
sprintf(out, "/var/tmp/rtty.out.%d", getpid());
if(mkfifo(in, 0644) == -1 || mkfifo(out, 0664) == -1)
if(errno != EEXIST)
err(1, "mkfifo");
- /* Process rtty-specific flags. */
escape = dumb = interactive = sshpass = 0;
for(;argv[1][0] == '+';){
if(strchr(argv[1], 'd')) dumb = 1;
@@ -52,12 +50,11 @@ main(int argc, char *argv[])
if(strchr(argv[1], 'x')) escape = 1;
if(strchr(argv[1], 'p')) sshpass = 1;
- /* Remove flag argument from argv. */
argv[1] = argv[0];
argv++; argc--;
}
- /* Save pointer to address argument. */
+ /* Save server address (first non-flag argument). */
address = NULL;
for(i = 1; i < argc; i++)
if(argv[i][0] != '-'){
@@ -65,7 +62,6 @@ main(int argc, char *argv[])
break;
}
- /* If +p is given, immediately ask for password. */
if(sshpass){
printf("password: ");
getpw(pw);
@@ -73,11 +69,7 @@ main(int argc, char *argv[])
sshpass = 1;
}
- /*
- * A child ssh process is created, with standard in connected to
- * the input pipe (fdin) and standard out connected to the output
- * pipe (fdout).
- */
+ /* Start ssh. */
if(fork() == 0){
if(!(fdin = open(in, O_RDONLY)))
err(1, "open");
@@ -86,7 +78,6 @@ main(int argc, char *argv[])
dup2(fdin, 0);
dup2(fdout, 1);
- /* Create new argument vector. */
if(!(nargv = malloc(sizeof(char *)*(argc+10))))
err(1, "malloc");
offset = -1;
@@ -104,7 +95,6 @@ main(int argc, char *argv[])
signal(SIGINT, SIG_IGN);
- /* Exec into ssh. */
execvp(nargv[0], nargv);
err(1, "%s", nargv[0]);
}
@@ -114,7 +104,7 @@ main(int argc, char *argv[])
if(!(fdout = open(out, O_RDONLY)))
err(1, "open");
- /* Print initialization command. */
+ /* Initialize remote environment. */
if(interactive)
dprintf(fdin, IINIT);
else
@@ -137,13 +127,8 @@ main(int argc, char *argv[])
bufin[n] = 0;
/*
- * As +x is given, escaped commands are enabled,
- * prefixed with !. Escaped commands are run
- * locally, but operate on remote files. Any
- * specified remote files will be downloaded and
- * re-uploaded when the escaped command finishes.
- * (Escaped commands are recognized only after
- * shell prompt.)
+ * Escaped commands are recognized only after a
+ * remote shell prompt.
*/
if(!(escape && bufin[0] == '!'
&& (strcmp(bufout+strlen(bufout)-2, "$ ") == 0
@@ -154,11 +139,8 @@ main(int argc, char *argv[])
}
/*
- * The remote server is queried for the current
- * working directory. The response contains the
- * query ("pwd\n"), which is skipped, followed by
- * the working directory ("/some/path\n") and then
- * a shell prompt, which is skipped.
+ * Get remote working directory. (The response
+ * looks like "pwd\n(directory)\n(prompt)".)
*/
dprintf(fdin, "pwd\n");
for(i = 0; i < MAXWD-1; i++){
@@ -168,12 +150,11 @@ main(int argc, char *argv[])
n = read(fdout, wd, MAXWD);
wd[strcspn(wd, "\n\015")] = 0;
- /* Construct corresponding argument vector. */
bufin[strcspn(bufin, "\n")] = 0;
- p = bufin+1;
i = 0;
- for(q = strtok(p, " "); q;
- (q = strtok(NULL, " ")), i++)
+ p = bufin+1;
+ q = strtok(p, " ");
+ for(; q; (q = strtok(NULL, " ")), i++)
if(i < MAXEARG-1)
eargv[i] = q;
eargv[i] = NULL;
@@ -182,8 +163,10 @@ main(int argc, char *argv[])
if(eargv[i][0] != '-'
&& eargv[i][0] != '+')
goto found;
+
fprintf(stderr, "no file specified\n");
goto done;
+
found:
if(eargv[i+1]){
fprintf(stderr,
@@ -191,7 +174,6 @@ found:
goto done;
}
- /* Create a temporary local directory. */
strcpy(dir, "/tmp/rtty.XXXXXX");
if(!mkdtemp(dir)){
warn("mkdtemp");
@@ -199,7 +181,7 @@ found:
}
chdir(dir);
- /* Construct argument to scp. */
+ /* Construct remote path for scp. */
if(!(p = malloc(strlen(address)-1+strlen(wd)-1
+strlen(eargv[i])-1+3)))
err(1, "malloc");
@@ -210,10 +192,6 @@ found:
q = strrchr(eargv[i], '/');
if(q) eargv[i] = q+1;
- /*
- * During the execution of the external commands,
- * the SIGCHLD handler is temporarily disabled.
- */
signal(SIGCHLD, NULL);
/* Download file. */
@@ -254,20 +232,14 @@ found:
goto done;
}
- /* Remove temporary directory. */
unlink(eargv[i]);
rmdir(dir);
- /* Clean up. */
done:
signal(SIGCHLD, killall);
free(p);
- /*
- * After an escaped command, an empty line is sent
- * to the remote server, in order for a new shell
- * prompt to be triggered.
- */
+ /* Trigger new remote shell prompt. */
dprintf(fdin, "\n");
}
@@ -281,12 +253,9 @@ done:
bufout[n] = 0;
/*
- * Bufin and bufout are copied to the temporary
- * pointers p and q. p is incremented in order to
- * skip any potential repetition of the command
- * given by the user on standard in. (It is assumed
- * that the typed command fits in bufin, i.e. is
- * not larger than MAXBUF.)
+ * The server's echo of the client's command is
+ * skipped, assuming that bufin contains the
+ * command in its entirety.
*/
p = bufin;
q = bufout;
@@ -306,20 +275,14 @@ done:
p++; q++;
}
- /*
- * Bo is printed and bufin is cleared, so as not
- * to perform the skip again, incorrectly.
- */
+ /* Don't skip the echo again. */
printf("%s", q);
fflush(stdout);
bufin[0] = 0;
- /*
- * Unless the +d flag is given, rtty tries to detect
- * password prompts and hide the user's input.
- */
if(dumb)
continue;
+
if(q[strlen(q)-1] == ':'
|| strcmp(q+strlen(q)-2, ": ") == 0){
if(!(q = strrchr(bufout, '\n')))