diff options
Diffstat (limited to 'sftp-server.c')
-rw-r--r-- | sftp-server.c | 220 |
1 files changed, 167 insertions, 53 deletions
diff --git a/sftp-server.c b/sftp-server.c index 76edebc5a..24c4ff717 100644 --- a/sftp-server.c +++ b/sftp-server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-server.c,v 1.73 2007/05/17 07:55:29 djm Exp $ */ | 1 | /* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -23,6 +23,12 @@ | |||
23 | #ifdef HAVE_SYS_TIME_H | 23 | #ifdef HAVE_SYS_TIME_H |
24 | # include <sys/time.h> | 24 | # include <sys/time.h> |
25 | #endif | 25 | #endif |
26 | #ifdef HAVE_SYS_MOUNT_H | ||
27 | #include <sys/mount.h> | ||
28 | #endif | ||
29 | #ifdef HAVE_SYS_STATVFS_H | ||
30 | #include <sys/statvfs.h> | ||
31 | #endif | ||
26 | 32 | ||
27 | #include <dirent.h> | 33 | #include <dirent.h> |
28 | #include <errno.h> | 34 | #include <errno.h> |
@@ -98,6 +104,9 @@ errno_to_portable(int unixerrno) | |||
98 | case EINVAL: | 104 | case EINVAL: |
99 | ret = SSH2_FX_BAD_MESSAGE; | 105 | ret = SSH2_FX_BAD_MESSAGE; |
100 | break; | 106 | break; |
107 | case ENOSYS: | ||
108 | ret = SSH2_FX_OP_UNSUPPORTED; | ||
109 | break; | ||
101 | default: | 110 | default: |
102 | ret = SSH2_FX_FAILURE; | 111 | ret = SSH2_FX_FAILURE; |
103 | break; | 112 | break; |
@@ -169,6 +178,7 @@ struct Handle { | |||
169 | int fd; | 178 | int fd; |
170 | char *name; | 179 | char *name; |
171 | u_int64_t bytes_read, bytes_write; | 180 | u_int64_t bytes_read, bytes_write; |
181 | int next_unused; | ||
172 | }; | 182 | }; |
173 | 183 | ||
174 | enum { | 184 | enum { |
@@ -177,40 +187,46 @@ enum { | |||
177 | HANDLE_FILE | 187 | HANDLE_FILE |
178 | }; | 188 | }; |
179 | 189 | ||
180 | Handle handles[100]; | 190 | Handle *handles = NULL; |
191 | u_int num_handles = 0; | ||
192 | int first_unused_handle = -1; | ||
181 | 193 | ||
182 | static void | 194 | static void handle_unused(int i) |
183 | handle_init(void) | ||
184 | { | 195 | { |
185 | u_int i; | 196 | handles[i].use = HANDLE_UNUSED; |
186 | 197 | handles[i].next_unused = first_unused_handle; | |
187 | for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) | 198 | first_unused_handle = i; |
188 | handles[i].use = HANDLE_UNUSED; | ||
189 | } | 199 | } |
190 | 200 | ||
191 | static int | 201 | static int |
192 | handle_new(int use, const char *name, int fd, DIR *dirp) | 202 | handle_new(int use, const char *name, int fd, DIR *dirp) |
193 | { | 203 | { |
194 | u_int i; | 204 | int i; |
195 | 205 | ||
196 | for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) { | 206 | if (first_unused_handle == -1) { |
197 | if (handles[i].use == HANDLE_UNUSED) { | 207 | if (num_handles + 1 <= num_handles) |
198 | handles[i].use = use; | 208 | return -1; |
199 | handles[i].dirp = dirp; | 209 | num_handles++; |
200 | handles[i].fd = fd; | 210 | handles = xrealloc(handles, num_handles, sizeof(Handle)); |
201 | handles[i].name = xstrdup(name); | 211 | handle_unused(num_handles - 1); |
202 | handles[i].bytes_read = handles[i].bytes_write = 0; | ||
203 | return i; | ||
204 | } | ||
205 | } | 212 | } |
206 | return -1; | 213 | |
214 | i = first_unused_handle; | ||
215 | first_unused_handle = handles[i].next_unused; | ||
216 | |||
217 | handles[i].use = use; | ||
218 | handles[i].dirp = dirp; | ||
219 | handles[i].fd = fd; | ||
220 | handles[i].name = xstrdup(name); | ||
221 | handles[i].bytes_read = handles[i].bytes_write = 0; | ||
222 | |||
223 | return i; | ||
207 | } | 224 | } |
208 | 225 | ||
209 | static int | 226 | static int |
210 | handle_is_ok(int i, int type) | 227 | handle_is_ok(int i, int type) |
211 | { | 228 | { |
212 | return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) && | 229 | return i >= 0 && (u_int)i < num_handles && handles[i].use == type; |
213 | handles[i].use == type; | ||
214 | } | 230 | } |
215 | 231 | ||
216 | static int | 232 | static int |
@@ -300,12 +316,12 @@ handle_close(int handle) | |||
300 | 316 | ||
301 | if (handle_is_ok(handle, HANDLE_FILE)) { | 317 | if (handle_is_ok(handle, HANDLE_FILE)) { |
302 | ret = close(handles[handle].fd); | 318 | ret = close(handles[handle].fd); |
303 | handles[handle].use = HANDLE_UNUSED; | ||
304 | xfree(handles[handle].name); | 319 | xfree(handles[handle].name); |
320 | handle_unused(handle); | ||
305 | } else if (handle_is_ok(handle, HANDLE_DIR)) { | 321 | } else if (handle_is_ok(handle, HANDLE_DIR)) { |
306 | ret = closedir(handles[handle].dirp); | 322 | ret = closedir(handles[handle].dirp); |
307 | handles[handle].use = HANDLE_UNUSED; | ||
308 | xfree(handles[handle].name); | 323 | xfree(handles[handle].name); |
324 | handle_unused(handle); | ||
309 | } else { | 325 | } else { |
310 | errno = ENOENT; | 326 | errno = ENOENT; |
311 | } | 327 | } |
@@ -333,7 +349,7 @@ handle_log_exit(void) | |||
333 | { | 349 | { |
334 | u_int i; | 350 | u_int i; |
335 | 351 | ||
336 | for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) | 352 | for (i = 0; i < num_handles; i++) |
337 | if (handles[i].use != HANDLE_UNUSED) | 353 | if (handles[i].use != HANDLE_UNUSED) |
338 | handle_log_close(i, "forced"); | 354 | handle_log_close(i, "forced"); |
339 | } | 355 | } |
@@ -468,6 +484,33 @@ send_attrib(u_int32_t id, const Attrib *a) | |||
468 | buffer_free(&msg); | 484 | buffer_free(&msg); |
469 | } | 485 | } |
470 | 486 | ||
487 | static void | ||
488 | send_statvfs(u_int32_t id, struct statvfs *st) | ||
489 | { | ||
490 | Buffer msg; | ||
491 | u_int64_t flag; | ||
492 | |||
493 | flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; | ||
494 | flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; | ||
495 | |||
496 | buffer_init(&msg); | ||
497 | buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); | ||
498 | buffer_put_int(&msg, id); | ||
499 | buffer_put_int64(&msg, st->f_bsize); | ||
500 | buffer_put_int64(&msg, st->f_frsize); | ||
501 | buffer_put_int64(&msg, st->f_blocks); | ||
502 | buffer_put_int64(&msg, st->f_bfree); | ||
503 | buffer_put_int64(&msg, st->f_bavail); | ||
504 | buffer_put_int64(&msg, st->f_files); | ||
505 | buffer_put_int64(&msg, st->f_ffree); | ||
506 | buffer_put_int64(&msg, st->f_favail); | ||
507 | buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid)); | ||
508 | buffer_put_int64(&msg, flag); | ||
509 | buffer_put_int64(&msg, st->f_namemax); | ||
510 | send_msg(&msg); | ||
511 | buffer_free(&msg); | ||
512 | } | ||
513 | |||
471 | /* parse incoming */ | 514 | /* parse incoming */ |
472 | 515 | ||
473 | static void | 516 | static void |
@@ -480,6 +523,15 @@ process_init(void) | |||
480 | buffer_init(&msg); | 523 | buffer_init(&msg); |
481 | buffer_put_char(&msg, SSH2_FXP_VERSION); | 524 | buffer_put_char(&msg, SSH2_FXP_VERSION); |
482 | buffer_put_int(&msg, SSH2_FILEXFER_VERSION); | 525 | buffer_put_int(&msg, SSH2_FILEXFER_VERSION); |
526 | /* POSIX rename extension */ | ||
527 | buffer_put_cstring(&msg, "posix-rename@openssh.com"); | ||
528 | buffer_put_cstring(&msg, "1"); /* version */ | ||
529 | /* statvfs extension */ | ||
530 | buffer_put_cstring(&msg, "statvfs@openssh.com"); | ||
531 | buffer_put_cstring(&msg, "2"); /* version */ | ||
532 | /* fstatvfs extension */ | ||
533 | buffer_put_cstring(&msg, "fstatvfs@openssh.com"); | ||
534 | buffer_put_cstring(&msg, "2"); /* version */ | ||
483 | send_msg(&msg); | 535 | send_msg(&msg); |
484 | buffer_free(&msg); | 536 | buffer_free(&msg); |
485 | } | 537 | } |
@@ -711,7 +763,7 @@ process_setstat(void) | |||
711 | } | 763 | } |
712 | if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { | 764 | if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { |
713 | logit("set \"%s\" mode %04o", name, a->perm); | 765 | logit("set \"%s\" mode %04o", name, a->perm); |
714 | ret = chmod(name, a->perm & 0777); | 766 | ret = chmod(name, a->perm & 07777); |
715 | if (ret == -1) | 767 | if (ret == -1) |
716 | status = errno_to_portable(errno); | 768 | status = errno_to_portable(errno); |
717 | } | 769 | } |
@@ -765,9 +817,9 @@ process_fsetstat(void) | |||
765 | if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { | 817 | if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { |
766 | logit("set \"%s\" mode %04o", name, a->perm); | 818 | logit("set \"%s\" mode %04o", name, a->perm); |
767 | #ifdef HAVE_FCHMOD | 819 | #ifdef HAVE_FCHMOD |
768 | ret = fchmod(fd, a->perm & 0777); | 820 | ret = fchmod(fd, a->perm & 07777); |
769 | #else | 821 | #else |
770 | ret = chmod(name, a->perm & 0777); | 822 | ret = chmod(name, a->perm & 07777); |
771 | #endif | 823 | #endif |
772 | if (ret == -1) | 824 | if (ret == -1) |
773 | status = errno_to_portable(errno); | 825 | status = errno_to_portable(errno); |
@@ -918,7 +970,7 @@ process_mkdir(void) | |||
918 | name = get_string(NULL); | 970 | name = get_string(NULL); |
919 | a = get_attrib(); | 971 | a = get_attrib(); |
920 | mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? | 972 | mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? |
921 | a->perm & 0777 : 0777; | 973 | a->perm & 07777 : 0777; |
922 | debug3("request %u: mkdir", id); | 974 | debug3("request %u: mkdir", id); |
923 | logit("mkdir name \"%s\" mode 0%o", name, mode); | 975 | logit("mkdir name \"%s\" mode 0%o", name, mode); |
924 | ret = mkdir(name, mode); | 976 | ret = mkdir(name, mode); |
@@ -990,6 +1042,9 @@ process_rename(void) | |||
990 | /* Race-free rename of regular files */ | 1042 | /* Race-free rename of regular files */ |
991 | if (link(oldpath, newpath) == -1) { | 1043 | if (link(oldpath, newpath) == -1) { |
992 | if (errno == EOPNOTSUPP | 1044 | if (errno == EOPNOTSUPP |
1045 | #ifdef EXDEV | ||
1046 | || errno == EXDEV | ||
1047 | #endif | ||
993 | #ifdef LINK_OPNOTSUPP_ERRNO | 1048 | #ifdef LINK_OPNOTSUPP_ERRNO |
994 | || errno == LINK_OPNOTSUPP_ERRNO | 1049 | || errno == LINK_OPNOTSUPP_ERRNO |
995 | #endif | 1050 | #endif |
@@ -1073,6 +1128,59 @@ process_symlink(void) | |||
1073 | } | 1128 | } |
1074 | 1129 | ||
1075 | static void | 1130 | static void |
1131 | process_extended_posix_rename(u_int32_t id) | ||
1132 | { | ||
1133 | char *oldpath, *newpath; | ||
1134 | |||
1135 | oldpath = get_string(NULL); | ||
1136 | newpath = get_string(NULL); | ||
1137 | debug3("request %u: posix-rename", id); | ||
1138 | logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); | ||
1139 | if (rename(oldpath, newpath) == -1) | ||
1140 | send_status(id, errno_to_portable(errno)); | ||
1141 | else | ||
1142 | send_status(id, SSH2_FX_OK); | ||
1143 | xfree(oldpath); | ||
1144 | xfree(newpath); | ||
1145 | } | ||
1146 | |||
1147 | static void | ||
1148 | process_extended_statvfs(u_int32_t id) | ||
1149 | { | ||
1150 | char *path; | ||
1151 | struct statvfs st; | ||
1152 | |||
1153 | path = get_string(NULL); | ||
1154 | debug3("request %u: statfs", id); | ||
1155 | logit("statfs \"%s\"", path); | ||
1156 | |||
1157 | if (statvfs(path, &st) != 0) | ||
1158 | send_status(id, errno_to_portable(errno)); | ||
1159 | else | ||
1160 | send_statvfs(id, &st); | ||
1161 | xfree(path); | ||
1162 | } | ||
1163 | |||
1164 | static void | ||
1165 | process_extended_fstatvfs(u_int32_t id) | ||
1166 | { | ||
1167 | int handle, fd; | ||
1168 | struct statvfs st; | ||
1169 | |||
1170 | handle = get_handle(); | ||
1171 | debug("request %u: fstatvfs \"%s\" (handle %u)", | ||
1172 | id, handle_to_name(handle), handle); | ||
1173 | if ((fd = handle_to_fd(handle)) < 0) { | ||
1174 | send_status(id, SSH2_FX_FAILURE); | ||
1175 | return; | ||
1176 | } | ||
1177 | if (fstatvfs(fd, &st) != 0) | ||
1178 | send_status(id, errno_to_portable(errno)); | ||
1179 | else | ||
1180 | send_statvfs(id, &st); | ||
1181 | } | ||
1182 | |||
1183 | static void | ||
1076 | process_extended(void) | 1184 | process_extended(void) |
1077 | { | 1185 | { |
1078 | u_int32_t id; | 1186 | u_int32_t id; |
@@ -1080,7 +1188,14 @@ process_extended(void) | |||
1080 | 1188 | ||
1081 | id = get_int(); | 1189 | id = get_int(); |
1082 | request = get_string(NULL); | 1190 | request = get_string(NULL); |
1083 | send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ | 1191 | if (strcmp(request, "posix-rename@openssh.com") == 0) |
1192 | process_extended_posix_rename(id); | ||
1193 | else if (strcmp(request, "statvfs@openssh.com") == 0) | ||
1194 | process_extended_statvfs(id); | ||
1195 | else if (strcmp(request, "fstatvfs@openssh.com") == 0) | ||
1196 | process_extended_fstatvfs(id); | ||
1197 | else | ||
1198 | send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ | ||
1084 | xfree(request); | 1199 | xfree(request); |
1085 | } | 1200 | } |
1086 | 1201 | ||
@@ -1103,7 +1218,7 @@ process(void) | |||
1103 | if (msg_len > SFTP_MAX_MSG_LENGTH) { | 1218 | if (msg_len > SFTP_MAX_MSG_LENGTH) { |
1104 | error("bad message from %s local user %s", | 1219 | error("bad message from %s local user %s", |
1105 | client_addr, pw->pw_name); | 1220 | client_addr, pw->pw_name); |
1106 | cleanup_exit(11); | 1221 | sftp_server_cleanup_exit(11); |
1107 | } | 1222 | } |
1108 | if (buf_len < msg_len + 4) | 1223 | if (buf_len < msg_len + 4) |
1109 | return; | 1224 | return; |
@@ -1176,18 +1291,22 @@ process(void) | |||
1176 | break; | 1291 | break; |
1177 | } | 1292 | } |
1178 | /* discard the remaining bytes from the current packet */ | 1293 | /* discard the remaining bytes from the current packet */ |
1179 | if (buf_len < buffer_len(&iqueue)) | 1294 | if (buf_len < buffer_len(&iqueue)) { |
1180 | fatal("iqueue grew unexpectedly"); | 1295 | error("iqueue grew unexpectedly"); |
1296 | sftp_server_cleanup_exit(255); | ||
1297 | } | ||
1181 | consumed = buf_len - buffer_len(&iqueue); | 1298 | consumed = buf_len - buffer_len(&iqueue); |
1182 | if (msg_len < consumed) | 1299 | if (msg_len < consumed) { |
1183 | fatal("msg_len %d < consumed %d", msg_len, consumed); | 1300 | error("msg_len %d < consumed %d", msg_len, consumed); |
1301 | sftp_server_cleanup_exit(255); | ||
1302 | } | ||
1184 | if (msg_len > consumed) | 1303 | if (msg_len > consumed) |
1185 | buffer_consume(&iqueue, msg_len - consumed); | 1304 | buffer_consume(&iqueue, msg_len - consumed); |
1186 | } | 1305 | } |
1187 | 1306 | ||
1188 | /* Cleanup handler that logs active handles upon normal exit */ | 1307 | /* Cleanup handler that logs active handles upon normal exit */ |
1189 | void | 1308 | void |
1190 | cleanup_exit(int i) | 1309 | sftp_server_cleanup_exit(int i) |
1191 | { | 1310 | { |
1192 | if (pw != NULL && client_addr != NULL) { | 1311 | if (pw != NULL && client_addr != NULL) { |
1193 | handle_log_exit(); | 1312 | handle_log_exit(); |
@@ -1198,7 +1317,7 @@ cleanup_exit(int i) | |||
1198 | } | 1317 | } |
1199 | 1318 | ||
1200 | static void | 1319 | static void |
1201 | usage(void) | 1320 | sftp_server_usage(void) |
1202 | { | 1321 | { |
1203 | extern char *__progname; | 1322 | extern char *__progname; |
1204 | 1323 | ||
@@ -1208,7 +1327,7 @@ usage(void) | |||
1208 | } | 1327 | } |
1209 | 1328 | ||
1210 | int | 1329 | int |
1211 | main(int argc, char **argv) | 1330 | sftp_server_main(int argc, char **argv, struct passwd *user_pw) |
1212 | { | 1331 | { |
1213 | fd_set *rset, *wset; | 1332 | fd_set *rset, *wset; |
1214 | int in, out, max, ch, skipargs = 0, log_stderr = 0; | 1333 | int in, out, max, ch, skipargs = 0, log_stderr = 0; |
@@ -1219,9 +1338,6 @@ main(int argc, char **argv) | |||
1219 | extern char *optarg; | 1338 | extern char *optarg; |
1220 | extern char *__progname; | 1339 | extern char *__progname; |
1221 | 1340 | ||
1222 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | ||
1223 | sanitise_stdfd(); | ||
1224 | |||
1225 | __progname = ssh_get_progname(argv[0]); | 1341 | __progname = ssh_get_progname(argv[0]); |
1226 | log_init(__progname, log_level, log_facility, log_stderr); | 1342 | log_init(__progname, log_level, log_facility, log_stderr); |
1227 | 1343 | ||
@@ -1244,12 +1360,12 @@ main(int argc, char **argv) | |||
1244 | break; | 1360 | break; |
1245 | case 'f': | 1361 | case 'f': |
1246 | log_facility = log_facility_number(optarg); | 1362 | log_facility = log_facility_number(optarg); |
1247 | if (log_level == SYSLOG_FACILITY_NOT_SET) | 1363 | if (log_facility == SYSLOG_FACILITY_NOT_SET) |
1248 | error("Invalid log facility \"%s\"", optarg); | 1364 | error("Invalid log facility \"%s\"", optarg); |
1249 | break; | 1365 | break; |
1250 | case 'h': | 1366 | case 'h': |
1251 | default: | 1367 | default: |
1252 | usage(); | 1368 | sftp_server_usage(); |
1253 | } | 1369 | } |
1254 | } | 1370 | } |
1255 | 1371 | ||
@@ -1257,22 +1373,20 @@ main(int argc, char **argv) | |||
1257 | 1373 | ||
1258 | if ((cp = getenv("SSH_CONNECTION")) != NULL) { | 1374 | if ((cp = getenv("SSH_CONNECTION")) != NULL) { |
1259 | client_addr = xstrdup(cp); | 1375 | client_addr = xstrdup(cp); |
1260 | if ((cp = strchr(client_addr, ' ')) == NULL) | 1376 | if ((cp = strchr(client_addr, ' ')) == NULL) { |
1261 | fatal("Malformed SSH_CONNECTION variable: \"%s\"", | 1377 | error("Malformed SSH_CONNECTION variable: \"%s\"", |
1262 | getenv("SSH_CONNECTION")); | 1378 | getenv("SSH_CONNECTION")); |
1379 | sftp_server_cleanup_exit(255); | ||
1380 | } | ||
1263 | *cp = '\0'; | 1381 | *cp = '\0'; |
1264 | } else | 1382 | } else |
1265 | client_addr = xstrdup("UNKNOWN"); | 1383 | client_addr = xstrdup("UNKNOWN"); |
1266 | 1384 | ||
1267 | if ((pw = getpwuid(getuid())) == NULL) | 1385 | pw = pwcopy(user_pw); |
1268 | fatal("No user found for uid %lu", (u_long)getuid()); | ||
1269 | pw = pwcopy(pw); | ||
1270 | 1386 | ||
1271 | logit("session opened for local user %s from [%s]", | 1387 | logit("session opened for local user %s from [%s]", |
1272 | pw->pw_name, client_addr); | 1388 | pw->pw_name, client_addr); |
1273 | 1389 | ||
1274 | handle_init(); | ||
1275 | |||
1276 | in = dup(STDIN_FILENO); | 1390 | in = dup(STDIN_FILENO); |
1277 | out = dup(STDOUT_FILENO); | 1391 | out = dup(STDOUT_FILENO); |
1278 | 1392 | ||
@@ -1315,7 +1429,7 @@ main(int argc, char **argv) | |||
1315 | if (errno == EINTR) | 1429 | if (errno == EINTR) |
1316 | continue; | 1430 | continue; |
1317 | error("select: %s", strerror(errno)); | 1431 | error("select: %s", strerror(errno)); |
1318 | cleanup_exit(2); | 1432 | sftp_server_cleanup_exit(2); |
1319 | } | 1433 | } |
1320 | 1434 | ||
1321 | /* copy stdin to iqueue */ | 1435 | /* copy stdin to iqueue */ |
@@ -1323,10 +1437,10 @@ main(int argc, char **argv) | |||
1323 | len = read(in, buf, sizeof buf); | 1437 | len = read(in, buf, sizeof buf); |
1324 | if (len == 0) { | 1438 | if (len == 0) { |
1325 | debug("read eof"); | 1439 | debug("read eof"); |
1326 | cleanup_exit(0); | 1440 | sftp_server_cleanup_exit(0); |
1327 | } else if (len < 0) { | 1441 | } else if (len < 0) { |
1328 | error("read: %s", strerror(errno)); | 1442 | error("read: %s", strerror(errno)); |
1329 | cleanup_exit(1); | 1443 | sftp_server_cleanup_exit(1); |
1330 | } else { | 1444 | } else { |
1331 | buffer_append(&iqueue, buf, len); | 1445 | buffer_append(&iqueue, buf, len); |
1332 | } | 1446 | } |
@@ -1336,7 +1450,7 @@ main(int argc, char **argv) | |||
1336 | len = write(out, buffer_ptr(&oqueue), olen); | 1450 | len = write(out, buffer_ptr(&oqueue), olen); |
1337 | if (len < 0) { | 1451 | if (len < 0) { |
1338 | error("write: %s", strerror(errno)); | 1452 | error("write: %s", strerror(errno)); |
1339 | cleanup_exit(1); | 1453 | sftp_server_cleanup_exit(1); |
1340 | } else { | 1454 | } else { |
1341 | buffer_consume(&oqueue, len); | 1455 | buffer_consume(&oqueue, len); |
1342 | } | 1456 | } |