1 /* $OpenBSD: sftp-server.c,v 1.59 2006/07/09 15:15:11 stevesk Exp $ */
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
34 #include "sftp-common.h"
37 #define get_int64() buffer_get_int64(&iqueue);
38 #define get_int() buffer_get_int(&iqueue);
39 #define get_string(lenp) buffer_get_string(&iqueue, lenp);
42 LogLevel log_level = SYSLOG_LEVEL_ERROR;
45 struct passwd *pw = NULL;
46 char *client_addr = NULL;
48 /* input and output queue */
52 /* Version of client */
55 /* portable attributes, etc. */
57 typedef struct Stat Stat;
66 errno_to_portable(int unixerrno)
78 ret = SSH2_FX_NO_SUCH_FILE;
83 ret = SSH2_FX_PERMISSION_DENIED;
87 ret = SSH2_FX_BAD_MESSAGE;
90 ret = SSH2_FX_FAILURE;
97 flags_from_portable(int pflags)
101 if ((pflags & SSH2_FXF_READ) &&
102 (pflags & SSH2_FXF_WRITE)) {
104 } else if (pflags & SSH2_FXF_READ) {
106 } else if (pflags & SSH2_FXF_WRITE) {
109 if (pflags & SSH2_FXF_CREAT)
111 if (pflags & SSH2_FXF_TRUNC)
113 if (pflags & SSH2_FXF_EXCL)
119 string_from_portable(int pflags)
121 static char ret[128];
125 #define PAPPEND(str) { \
127 strlcat(ret, ",", sizeof(ret)); \
128 strlcat(ret, str, sizeof(ret)); \
131 if (pflags & SSH2_FXF_READ)
133 if (pflags & SSH2_FXF_WRITE)
135 if (pflags & SSH2_FXF_CREAT)
137 if (pflags & SSH2_FXF_TRUNC)
139 if (pflags & SSH2_FXF_EXCL)
148 return decode_attrib(&iqueue);
153 typedef struct Handle Handle;
159 u_int64_t bytes_read, bytes_write;
175 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
176 handles[i].use = HANDLE_UNUSED;
180 handle_new(int use, const char *name, int fd, DIR *dirp)
184 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
185 if (handles[i].use == HANDLE_UNUSED) {
186 handles[i].use = use;
187 handles[i].dirp = dirp;
189 handles[i].name = xstrdup(name);
190 handles[i].bytes_read = handles[i].bytes_write = 0;
198 handle_is_ok(int i, int type)
200 return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) &&
201 handles[i].use == type;
205 handle_to_string(int handle, char **stringp, int *hlenp)
207 if (stringp == NULL || hlenp == NULL)
209 *stringp = xmalloc(sizeof(int32_t));
210 put_u32(*stringp, handle);
211 *hlenp = sizeof(int32_t);
216 handle_from_string(const char *handle, u_int hlen)
220 if (hlen != sizeof(int32_t))
222 val = get_u32(handle);
223 if (handle_is_ok(val, HANDLE_FILE) ||
224 handle_is_ok(val, HANDLE_DIR))
230 handle_to_name(int handle)
232 if (handle_is_ok(handle, HANDLE_DIR)||
233 handle_is_ok(handle, HANDLE_FILE))
234 return handles[handle].name;
239 handle_to_dir(int handle)
241 if (handle_is_ok(handle, HANDLE_DIR))
242 return handles[handle].dirp;
247 handle_to_fd(int handle)
249 if (handle_is_ok(handle, HANDLE_FILE))
250 return handles[handle].fd;
255 handle_update_read(int handle, ssize_t bytes)
257 if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
258 handles[handle].bytes_read += bytes;
262 handle_update_write(int handle, ssize_t bytes)
264 if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
265 handles[handle].bytes_write += bytes;
269 handle_bytes_read(int handle)
271 if (handle_is_ok(handle, HANDLE_FILE))
272 return (handles[handle].bytes_read);
277 handle_bytes_write(int handle)
279 if (handle_is_ok(handle, HANDLE_FILE))
280 return (handles[handle].bytes_write);
285 handle_close(int handle)
289 if (handle_is_ok(handle, HANDLE_FILE)) {
290 ret = close(handles[handle].fd);
291 handles[handle].use = HANDLE_UNUSED;
292 xfree(handles[handle].name);
293 } else if (handle_is_ok(handle, HANDLE_DIR)) {
294 ret = closedir(handles[handle].dirp);
295 handles[handle].use = HANDLE_UNUSED;
296 xfree(handles[handle].name);
304 handle_log_close(int handle, char *emsg)
306 if (handle_is_ok(handle, HANDLE_FILE)) {
307 logit("%s%sclose \"%s\" bytes read %llu written %llu",
308 emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
309 handle_to_name(handle),
310 handle_bytes_read(handle), handle_bytes_write(handle));
312 logit("%s%sclosedir \"%s\"",
313 emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
314 handle_to_name(handle));
319 handle_log_exit(void)
323 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
324 if (handles[i].use != HANDLE_UNUSED)
325 handle_log_close(i, "forced");
335 handle = get_string(&hlen);
337 val = handle_from_string(handle, hlen);
347 int mlen = buffer_len(m);
349 buffer_put_int(&oqueue, mlen);
350 buffer_append(&oqueue, buffer_ptr(m), mlen);
351 buffer_consume(m, mlen);
355 status_to_message(u_int32_t status)
357 const char *status_messages[] = {
358 "Success", /* SSH_FX_OK */
359 "End of file", /* SSH_FX_EOF */
360 "No such file", /* SSH_FX_NO_SUCH_FILE */
361 "Permission denied", /* SSH_FX_PERMISSION_DENIED */
362 "Failure", /* SSH_FX_FAILURE */
363 "Bad message", /* SSH_FX_BAD_MESSAGE */
364 "No connection", /* SSH_FX_NO_CONNECTION */
365 "Connection lost", /* SSH_FX_CONNECTION_LOST */
366 "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
367 "Unknown error" /* Others */
369 return (status_messages[MIN(status,SSH2_FX_MAX)]);
373 send_status(u_int32_t id, u_int32_t status)
377 debug3("request %u: sent status %u", id, status);
378 if (log_level > SYSLOG_LEVEL_VERBOSE ||
379 (status != SSH2_FX_OK && status != SSH2_FX_EOF))
380 logit("sent status %s", status_to_message(status));
382 buffer_put_char(&msg, SSH2_FXP_STATUS);
383 buffer_put_int(&msg, id);
384 buffer_put_int(&msg, status);
386 buffer_put_cstring(&msg, status_to_message(status));
387 buffer_put_cstring(&msg, "");
393 send_data_or_handle(char type, u_int32_t id, const char *data, int dlen)
398 buffer_put_char(&msg, type);
399 buffer_put_int(&msg, id);
400 buffer_put_string(&msg, data, dlen);
406 send_data(u_int32_t id, const char *data, int dlen)
408 debug("request %u: sent data len %d", id, dlen);
409 send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
413 send_handle(u_int32_t id, int handle)
418 handle_to_string(handle, &string, &hlen);
419 debug("request %u: sent handle handle %d", id, handle);
420 send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
425 send_names(u_int32_t id, int count, const Stat *stats)
431 buffer_put_char(&msg, SSH2_FXP_NAME);
432 buffer_put_int(&msg, id);
433 buffer_put_int(&msg, count);
434 debug("request %u: sent names count %d", id, count);
435 for (i = 0; i < count; i++) {
436 buffer_put_cstring(&msg, stats[i].name);
437 buffer_put_cstring(&msg, stats[i].long_name);
438 encode_attrib(&msg, &stats[i].attrib);
445 send_attrib(u_int32_t id, const Attrib *a)
449 debug("request %u: sent attrib have 0x%x", id, a->flags);
451 buffer_put_char(&msg, SSH2_FXP_ATTRS);
452 buffer_put_int(&msg, id);
453 encode_attrib(&msg, a);
466 verbose("received client version %d", version);
468 buffer_put_char(&msg, SSH2_FXP_VERSION);
469 buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
477 u_int32_t id, pflags;
480 int handle, fd, flags, mode, status = SSH2_FX_FAILURE;
483 debug3("request %u: open flags %d", id, pflags);
484 name = get_string(NULL);
485 pflags = get_int(); /* portable flags */
487 flags = flags_from_portable(pflags);
488 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
489 logit("open \"%s\" flags %s mode 0%o",
490 name, string_from_portable(pflags), mode);
491 fd = open(name, flags, mode);
493 status = errno_to_portable(errno);
495 handle = handle_new(HANDLE_FILE, name, fd, NULL);
499 send_handle(id, handle);
503 if (status != SSH2_FX_OK)
504 send_status(id, status);
512 int handle, ret, status = SSH2_FX_FAILURE;
515 handle = get_handle();
516 debug3("request %u: close handle %u", id, handle);
517 handle_log_close(handle, NULL);
518 ret = handle_close(handle);
519 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
520 send_status(id, status);
528 int handle, fd, ret, status = SSH2_FX_FAILURE;
532 handle = get_handle();
536 debug("request %u: read \"%s\" (handle %d) off %llu len %d",
537 id, handle_to_name(handle), handle, (unsigned long long)off, len);
538 if (len > sizeof buf) {
540 debug2("read change len %d", len);
542 fd = handle_to_fd(handle);
544 if (lseek(fd, off, SEEK_SET) < 0) {
545 error("process_read: seek failed");
546 status = errno_to_portable(errno);
548 ret = read(fd, buf, len);
550 status = errno_to_portable(errno);
551 } else if (ret == 0) {
552 status = SSH2_FX_EOF;
554 send_data(id, buf, ret);
556 handle_update_read(handle, ret);
560 if (status != SSH2_FX_OK)
561 send_status(id, status);
570 int handle, fd, ret, status = SSH2_FX_FAILURE;
574 handle = get_handle();
576 data = get_string(&len);
578 debug("request %u: write \"%s\" (handle %d) off %llu len %d",
579 id, handle_to_name(handle), handle, (unsigned long long)off, len);
580 fd = handle_to_fd(handle);
582 if (lseek(fd, off, SEEK_SET) < 0) {
583 status = errno_to_portable(errno);
584 error("process_write: seek failed");
587 ret = write(fd, data, len);
589 error("process_write: write failed");
590 status = errno_to_portable(errno);
591 } else if ((size_t)ret == len) {
593 handle_update_write(handle, ret);
595 debug2("nothing at all written");
599 send_status(id, status);
604 process_do_stat(int do_lstat)
610 int ret, status = SSH2_FX_FAILURE;
613 name = get_string(NULL);
614 debug3("request %u: %sstat", id, do_lstat ? "l" : "");
615 verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
616 ret = do_lstat ? lstat(name, &st) : stat(name, &st);
618 status = errno_to_portable(errno);
620 stat_to_attrib(&st, &a);
624 if (status != SSH2_FX_OK)
625 send_status(id, status);
647 int fd, ret, handle, status = SSH2_FX_FAILURE;
650 handle = get_handle();
651 debug("request %u: fstat \"%s\" (handle %u)",
652 id, handle_to_name(handle), handle);
653 fd = handle_to_fd(handle);
655 ret = fstat(fd, &st);
657 status = errno_to_portable(errno);
659 stat_to_attrib(&st, &a);
664 if (status != SSH2_FX_OK)
665 send_status(id, status);
668 static struct timeval *
669 attrib_to_tv(const Attrib *a)
671 static struct timeval tv[2];
673 tv[0].tv_sec = a->atime;
675 tv[1].tv_sec = a->mtime;
681 process_setstat(void)
686 int status = SSH2_FX_OK, ret;
689 name = get_string(NULL);
691 debug("request %u: setstat name \"%s\"", id, name);
692 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
693 logit("set \"%s\" size %llu", name, a->size);
694 ret = truncate(name, a->size);
696 status = errno_to_portable(errno);
698 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
699 logit("set \"%s\" mode %04o", name, a->perm);
700 ret = chmod(name, a->perm & 0777);
702 status = errno_to_portable(errno);
704 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
708 strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
710 logit("set \"%s\" modtime %s", name, buf);
711 ret = utimes(name, attrib_to_tv(a));
713 status = errno_to_portable(errno);
715 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
716 logit("set \"%s\" owner %lu group %lu", name,
717 (u_long)a->uid, (u_long)a->gid);
718 ret = chown(name, a->uid, a->gid);
720 status = errno_to_portable(errno);
722 send_status(id, status);
727 process_fsetstat(void)
732 int status = SSH2_FX_OK;
735 handle = get_handle();
737 debug("request %u: fsetstat handle %d", id, handle);
738 fd = handle_to_fd(handle);
740 status = SSH2_FX_FAILURE;
742 char *name = handle_to_name(handle);
744 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
745 logit("set \"%s\" size %llu", name, a->size);
746 ret = ftruncate(fd, a->size);
748 status = errno_to_portable(errno);
750 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
751 logit("set \"%s\" mode %04o", name, a->perm);
753 ret = fchmod(fd, a->perm & 0777);
755 ret = chmod(name, a->perm & 0777);
758 status = errno_to_portable(errno);
760 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
764 strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
766 logit("set \"%s\" modtime %s", name, buf);
768 ret = futimes(fd, attrib_to_tv(a));
770 ret = utimes(name, attrib_to_tv(a));
773 status = errno_to_portable(errno);
775 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
776 logit("set \"%s\" owner %lu group %lu", name,
777 (u_long)a->uid, (u_long)a->gid);
779 ret = fchown(fd, a->uid, a->gid);
781 ret = chown(name, a->uid, a->gid);
784 status = errno_to_portable(errno);
787 send_status(id, status);
791 process_opendir(void)
795 int handle, status = SSH2_FX_FAILURE;
799 path = get_string(NULL);
800 debug3("request %u: opendir", id);
801 logit("opendir \"%s\"", path);
802 dirp = opendir(path);
804 status = errno_to_portable(errno);
806 handle = handle_new(HANDLE_DIR, path, 0, dirp);
810 send_handle(id, handle);
815 if (status != SSH2_FX_OK)
816 send_status(id, status);
821 process_readdir(void)
830 handle = get_handle();
831 debug("request %u: readdir \"%s\" (handle %d)", id,
832 handle_to_name(handle), handle);
833 dirp = handle_to_dir(handle);
834 path = handle_to_name(handle);
835 if (dirp == NULL || path == NULL) {
836 send_status(id, SSH2_FX_FAILURE);
839 char pathname[MAXPATHLEN];
841 int nstats = 10, count = 0, i;
843 stats = xcalloc(nstats, sizeof(Stat));
844 while ((dp = readdir(dirp)) != NULL) {
845 if (count >= nstats) {
847 stats = xrealloc(stats, nstats, sizeof(Stat));
850 snprintf(pathname, sizeof pathname, "%s%s%s", path,
851 strcmp(path, "/") ? "/" : "", dp->d_name);
852 if (lstat(pathname, &st) < 0)
854 stat_to_attrib(&st, &(stats[count].attrib));
855 stats[count].name = xstrdup(dp->d_name);
856 stats[count].long_name = ls_file(dp->d_name, &st, 0);
858 /* send up to 100 entries in one message */
859 /* XXX check packet size instead */
864 send_names(id, count, stats);
865 for (i = 0; i < count; i++) {
866 xfree(stats[i].name);
867 xfree(stats[i].long_name);
870 send_status(id, SSH2_FX_EOF);
881 int status = SSH2_FX_FAILURE;
885 name = get_string(NULL);
886 debug3("request %u: remove", id);
887 logit("remove name \"%s\"", name);
889 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
890 send_status(id, status);
900 int ret, mode, status = SSH2_FX_FAILURE;
903 name = get_string(NULL);
905 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
906 a->perm & 0777 : 0777;
907 debug3("request %u: mkdir", id);
908 logit("mkdir name \"%s\" mode 0%o", name, mode);
909 ret = mkdir(name, mode);
910 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
911 send_status(id, status);
923 name = get_string(NULL);
924 debug3("request %u: rmdir", id);
925 logit("rmdir name \"%s\"", name);
927 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
928 send_status(id, status);
933 process_realpath(void)
935 char resolvedname[MAXPATHLEN];
940 path = get_string(NULL);
941 if (path[0] == '\0') {
945 debug3("request %u: realpath", id);
946 verbose("realpath \"%s\"", path);
947 if (realpath(path, resolvedname) == NULL) {
948 send_status(id, errno_to_portable(errno));
951 attrib_clear(&s.attrib);
952 s.name = s.long_name = resolvedname;
953 send_names(id, 1, &s);
962 char *oldpath, *newpath;
967 oldpath = get_string(NULL);
968 newpath = get_string(NULL);
969 debug3("request %u: rename", id);
970 logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
971 status = SSH2_FX_FAILURE;
972 if (lstat(oldpath, &sb) == -1)
973 status = errno_to_portable(errno);
974 else if (S_ISREG(sb.st_mode)) {
975 /* Race-free rename of regular files */
976 if (link(oldpath, newpath) == -1) {
977 if (errno == EOPNOTSUPP
978 #ifdef LINK_OPNOTSUPP_ERRNO
979 || errno == LINK_OPNOTSUPP_ERRNO
985 * fs doesn't support links, so fall back to
986 * stat+rename. This is racy.
988 if (stat(newpath, &st) == -1) {
989 if (rename(oldpath, newpath) == -1)
991 errno_to_portable(errno);
996 status = errno_to_portable(errno);
998 } else if (unlink(oldpath) == -1) {
999 status = errno_to_portable(errno);
1000 /* clean spare link */
1003 status = SSH2_FX_OK;
1004 } else if (stat(newpath, &sb) == -1) {
1005 if (rename(oldpath, newpath) == -1)
1006 status = errno_to_portable(errno);
1008 status = SSH2_FX_OK;
1010 send_status(id, status);
1016 process_readlink(void)
1020 char buf[MAXPATHLEN];
1024 path = get_string(NULL);
1025 debug3("request %u: readlink", id);
1026 verbose("readlink \"%s\"", path);
1027 if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
1028 send_status(id, errno_to_portable(errno));
1033 attrib_clear(&s.attrib);
1034 s.name = s.long_name = buf;
1035 send_names(id, 1, &s);
1041 process_symlink(void)
1044 char *oldpath, *newpath;
1048 oldpath = get_string(NULL);
1049 newpath = get_string(NULL);
1050 debug3("request %u: symlink", id);
1051 logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
1052 /* this will fail if 'newpath' exists */
1053 ret = symlink(oldpath, newpath);
1054 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
1055 send_status(id, status);
1061 process_extended(void)
1067 request = get_string(NULL);
1068 send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
1072 /* stolen from ssh-agent */
1083 buf_len = buffer_len(&iqueue);
1085 return; /* Incomplete message. */
1086 cp = buffer_ptr(&iqueue);
1087 msg_len = get_u32(cp);
1088 if (msg_len > SFTP_MAX_MSG_LENGTH) {
1089 error("bad message from %s local user %s",
1090 client_addr, pw->pw_name);
1093 if (buf_len < msg_len + 4)
1095 buffer_consume(&iqueue, 4);
1097 type = buffer_get_char(&iqueue);
1105 case SSH2_FXP_CLOSE:
1111 case SSH2_FXP_WRITE:
1114 case SSH2_FXP_LSTAT:
1117 case SSH2_FXP_FSTAT:
1120 case SSH2_FXP_SETSTAT:
1123 case SSH2_FXP_FSETSTAT:
1126 case SSH2_FXP_OPENDIR:
1129 case SSH2_FXP_READDIR:
1132 case SSH2_FXP_REMOVE:
1135 case SSH2_FXP_MKDIR:
1138 case SSH2_FXP_RMDIR:
1141 case SSH2_FXP_REALPATH:
1147 case SSH2_FXP_RENAME:
1150 case SSH2_FXP_READLINK:
1153 case SSH2_FXP_SYMLINK:
1156 case SSH2_FXP_EXTENDED:
1160 error("Unknown message %d", type);
1163 /* discard the remaining bytes from the current packet */
1164 if (buf_len < buffer_len(&iqueue))
1165 fatal("iqueue grew unexpectedly");
1166 consumed = buf_len - buffer_len(&iqueue);
1167 if (msg_len < consumed)
1168 fatal("msg_len %d < consumed %d", msg_len, consumed);
1169 if (msg_len > consumed)
1170 buffer_consume(&iqueue, msg_len - consumed);
1173 /* Cleanup handler that logs active handles upon normal exit */
1177 if (pw != NULL && client_addr != NULL) {
1179 logit("session closed for local user %s from [%s]",
1180 pw->pw_name, client_addr);
1188 extern char *__progname;
1191 "usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname);
1196 main(int argc, char **argv)
1198 fd_set *rset, *wset;
1199 int in, out, max, ch, skipargs = 0, log_stderr = 0;
1200 ssize_t len, olen, set_size;
1201 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
1205 extern char *optarg;
1206 extern char *__progname;
1208 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1211 __progname = ssh_get_progname(argv[0]);
1212 log_init(__progname, log_level, log_facility, log_stderr);
1214 while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) {
1218 * Ignore all arguments if we are invoked as a
1219 * shell using "sftp-server -c command"
1227 log_level = log_level_number(optarg);
1228 if (log_level == SYSLOG_LEVEL_NOT_SET)
1229 error("Invalid log level \"%s\"", optarg);
1232 log_facility = log_facility_number(optarg);
1233 if (log_level == SYSLOG_FACILITY_NOT_SET)
1234 error("Invalid log facility \"%s\"", optarg);
1242 log_init(__progname, log_level, log_facility, log_stderr);
1244 if ((cp = getenv("SSH_CONNECTION")) != NULL) {
1245 client_addr = xstrdup(cp);
1246 if ((cp = strchr(client_addr, ' ')) == NULL)
1247 fatal("Malformed SSH_CONNECTION variable: \"%s\"",
1248 getenv("SSH_CONNECTION"));
1251 client_addr = xstrdup("UNKNOWN");
1253 if ((pw = getpwuid(getuid())) == NULL)
1254 fatal("No user found for uid %lu", (u_long)getuid());
1257 logit("session opened for local user %s from [%s]",
1258 pw->pw_name, client_addr);
1262 in = dup(STDIN_FILENO);
1263 out = dup(STDOUT_FILENO);
1266 setmode(in, O_BINARY);
1267 setmode(out, O_BINARY);
1276 buffer_init(&iqueue);
1277 buffer_init(&oqueue);
1279 set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
1280 rset = (fd_set *)xmalloc(set_size);
1281 wset = (fd_set *)xmalloc(set_size);
1284 memset(rset, 0, set_size);
1285 memset(wset, 0, set_size);
1288 olen = buffer_len(&oqueue);
1292 if (select(max+1, rset, wset, NULL, NULL) < 0) {
1295 error("select: %s", strerror(errno));
1299 /* copy stdin to iqueue */
1300 if (FD_ISSET(in, rset)) {
1302 len = read(in, buf, sizeof buf);
1306 } else if (len < 0) {
1307 error("read: %s", strerror(errno));
1310 buffer_append(&iqueue, buf, len);
1313 /* send oqueue to stdout */
1314 if (FD_ISSET(out, wset)) {
1315 len = write(out, buffer_ptr(&oqueue), olen);
1317 error("write: %s", strerror(errno));
1320 buffer_consume(&oqueue, len);
1323 /* process requests from client */