Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/networking/tftp.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/networking/tftp.c
r2725 r3232 19 19 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 20 20 */ 21 22 //usage:#define tftp_trivial_usage 23 //usage: "[OPTIONS] HOST [PORT]" 24 //usage:#define tftp_full_usage "\n\n" 25 //usage: "Transfer a file from/to tftp server\n" 26 //usage: "\n -l FILE Local FILE" 27 //usage: "\n -r FILE Remote FILE" 28 //usage: IF_FEATURE_TFTP_GET( 29 //usage: "\n -g Get file" 30 //usage: ) 31 //usage: IF_FEATURE_TFTP_PUT( 32 //usage: "\n -p Put file" 33 //usage: ) 34 //usage: IF_FEATURE_TFTP_BLOCKSIZE( 35 //usage: "\n -b SIZE Transfer blocks of SIZE octets" 36 //usage: ) 37 //usage: 38 //usage:#define tftpd_trivial_usage 39 //usage: "[-cr] [-u USER] [DIR]" 40 //usage:#define tftpd_full_usage "\n\n" 41 //usage: "Transfer a file on tftp client's request\n" 42 //usage: "\n" 43 //usage: "tftpd should be used as an inetd service.\n" 44 //usage: "tftpd's line for inetd.conf:\n" 45 //usage: " 69 dgram udp nowait root tftpd tftpd -l /files/to/serve\n" 46 //usage: "It also can be ran from udpsvd:\n" 47 //usage: " udpsvd -vE 0.0.0.0 69 tftpd /files/to/serve\n" 48 //usage: "\n -r Prohibit upload" 49 //usage: "\n -c Allow file creation via upload" 50 //usage: "\n -u Access files as USER" 51 //usage: "\n -l Log to syslog (inetd mode requires this)" 52 21 53 #include "libbb.h" 54 #include <syslog.h> 22 55 23 56 #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT … … 60 93 TFTPD_OPT_c = (1 << 9) * ENABLE_TFTPD, 61 94 TFTPD_OPT_u = (1 << 10) * ENABLE_TFTPD, 95 TFTPD_OPT_l = (1 << 11) * ENABLE_TFTPD, 62 96 }; 63 97 … … 83 117 /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ 84 118 uint8_t error_pkt[4 + 32]; 85 char *user_opt;119 struct passwd *pw; 86 120 /* used in tftpd_main(), a bit big for stack: */ 87 121 char block_buf[TFTP_BLKSIZE_DEFAULT]; … … 97 131 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 98 132 }; 99 #define block_buf (G.block_buf )100 #define user_opt (G.user_opt )101 #define error_pkt (G.error_pkt )102 133 #define INIT_G() do { } while (0) 103 134 104 #define error_pkt_reason (error_pkt[3])105 #define error_pkt_str (error_pkt + 4)135 #define G_error_pkt_reason (G.error_pkt[3]) 136 #define G_error_pkt_str ((char*)(G.error_pkt + 4)) 106 137 107 138 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR 108 139 static void tftp_progress_update(void) 109 140 { 110 bb_progress_update(&G.pmt, G.file,0, G.pos, G.size);141 bb_progress_update(&G.pmt, 0, G.pos, G.size); 111 142 } 112 143 static void tftp_progress_init(void) 113 144 { 114 bb_progress_init(&G.pmt );145 bb_progress_init(&G.pmt, G.file); 115 146 tftp_progress_update(); 116 147 } 117 148 static void tftp_progress_done(void) 118 149 { 119 if ( G.pmt.inited) {150 if (is_bb_progress_inited(&G.pmt)) { 120 151 tftp_progress_update(); 121 152 bb_putchar_stderr('\n'); 122 G.pmt.inited = 0;153 bb_progress_free(&G.pmt); 123 154 } 124 155 } … … 239 270 240 271 /* Is there an error already? Send pkt and bail out */ 241 if ( error_pkt_reason ||error_pkt_str[0])272 if (G_error_pkt_reason || G_error_pkt_str[0]) 242 273 goto send_err_pkt; 243 274 244 if (user_opt) { 245 struct passwd *pw = xgetpwnam(user_opt); 246 change_identity(pw); /* initgroups, setgid, setuid */ 275 if (G.pw) { 276 change_identity(G.pw); /* initgroups, setgid, setuid */ 247 277 } 248 278 } … … 296 326 local_fd = open(local_file, open_mode, 0666); 297 327 if (local_fd < 0) { 298 error_pkt_reason = ERR_NOFILE;299 strcpy( (char*)error_pkt_str, "can't open file");328 G_error_pkt_reason = ERR_NOFILE; 329 strcpy(G_error_pkt_str, "can't open file"); 300 330 goto send_err_pkt; 301 331 } … … 423 453 } 424 454 cp += len; 455 IF_FEATURE_TFTP_PROGRESS_BAR(G.pos += len;) 425 456 } 426 457 send_pkt: … … 444 475 445 476 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR 446 if (ENABLE_TFTP && remote_file) /* tftp */ 447 G.pos = (block_nr - 1) * (uoff_t)blksize; 448 if (G.pmt.inited) 477 if (is_bb_progress_inited(&G.pmt)) 449 478 tftp_progress_update(); 450 479 #endif … … 543 572 blksize = tftp_blksize_check(res, blksize); 544 573 if (blksize < 0) { 545 error_pkt_reason = ERR_BAD_OPT;574 G_error_pkt_reason = ERR_BAD_OPT; 546 575 goto send_err_pkt; 547 576 } … … 582 611 int sz = full_write(local_fd, &rbuf[4], len - 4); 583 612 if (sz != len - 4) { 584 strcpy( (char*)error_pkt_str, bb_msg_write_error);585 error_pkt_reason = ERR_WRITE;613 strcpy(G_error_pkt_str, bb_msg_write_error); 614 G_error_pkt_reason = ERR_WRITE; 586 615 goto send_err_pkt; 587 616 } … … 589 618 finished = 1; 590 619 } 620 IF_FEATURE_TFTP_PROGRESS_BAR(G.pos += sz;) 591 621 continue; /* send ACK */ 592 622 } … … 631 661 632 662 send_read_err_pkt: 633 strcpy( (char*)error_pkt_str, bb_msg_read_error);663 strcpy(G_error_pkt_str, bb_msg_read_error); 634 664 send_err_pkt: 635 if ( error_pkt_str[0])636 bb_error_msg("%s", (char*)error_pkt_str);637 error_pkt[1] = TFTP_ERROR;638 xsendto(socket_fd, error_pkt, 4 + 1 + strlen((char*)error_pkt_str),665 if (G_error_pkt_str[0]) 666 bb_error_msg("%s", G_error_pkt_str); 667 G.error_pkt[1] = TFTP_ERROR; 668 xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str), 639 669 &peer_lsa->u.sa, peer_lsa->len); 640 670 return EXIT_FAILURE; … … 728 758 len_and_sockaddr *our_lsa; 729 759 len_and_sockaddr *peer_lsa; 730 char *local_file, *mode ;760 char *local_file, *mode, *user_opt; 731 761 const char *error_msg; 732 762 int opt, result, opcode; … … 750 780 751 781 /* Shifting to not collide with TFTP_OPTs */ 752 opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu: ", &user_opt) << 8);782 opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu:l", &user_opt) << 8); 753 783 argv += optind; 754 if (argv[0]) 755 xchdir(argv[0]); 756 757 result = recv_from_to(STDIN_FILENO, block_buf, sizeof(block_buf), 784 if (opt & TFTPD_OPT_l) { 785 openlog(applet_name, LOG_PID, LOG_DAEMON); 786 logmode = LOGMODE_SYSLOG; 787 } 788 if (opt & TFTPD_OPT_u) { 789 /* Must be before xchroot */ 790 G.pw = xgetpwnam(user_opt); 791 } 792 if (argv[0]) { 793 xchroot(argv[0]); 794 } 795 796 result = recv_from_to(STDIN_FILENO, G.block_buf, sizeof(G.block_buf), 758 797 0 /* flags */, 759 798 &peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len); 760 799 761 800 error_msg = "malformed packet"; 762 opcode = ntohs(*(uint16_t*) block_buf);763 if (result < 4 || result >= sizeof( block_buf)764 || block_buf[result-1] != '\0'801 opcode = ntohs(*(uint16_t*)G.block_buf); 802 if (result < 4 || result >= sizeof(G.block_buf) 803 || G.block_buf[result-1] != '\0' 765 804 || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ 766 805 IF_GETPUT(&&) … … 770 809 goto err; 771 810 } 772 local_file = block_buf + 2;811 local_file = G.block_buf + 2; 773 812 if (local_file[0] == '.' || strstr(local_file, "/.")) { 774 813 error_msg = "dot in file name"; … … 776 815 } 777 816 mode = local_file + strlen(local_file) + 1; 778 if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { 817 /* RFC 1350 says mode string is case independent */ 818 if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) { 779 819 goto err; 780 820 } … … 783 823 char *res; 784 824 char *opt_str = mode + sizeof("octet"); 785 int opt_len = block_buf + result - opt_str;825 int opt_len = G.block_buf + result - opt_str; 786 826 if (opt_len > 0) { 787 827 res = tftp_get_option("blksize", opt_str, opt_len); … … 789 829 blksize = tftp_blksize_check(res, 65564); 790 830 if (blksize < 0) { 791 error_pkt_reason = ERR_BAD_OPT;831 G_error_pkt_reason = ERR_BAD_OPT; 792 832 /* will just send error pkt */ 793 833 goto do_proto; … … 807 847 if (opt & TFTPD_OPT_r) { 808 848 /* This would mean "disk full" - not true */ 809 /* error_pkt_reason = ERR_WRITE;*/849 /*G_error_pkt_reason = ERR_WRITE;*/ 810 850 error_msg = bb_msg_write_error; 811 851 goto err; … … 816 856 } 817 857 818 /* NB: if error_pkt_str orerror_pkt_reason is set up,858 /* NB: if G_error_pkt_str or G_error_pkt_reason is set up, 819 859 * tftp_protocol() just sends one error pkt and returns */ 820 860 … … 831 871 return result; 832 872 err: 833 strcpy( (char*)error_pkt_str, error_msg);873 strcpy(G_error_pkt_str, error_msg); 834 874 goto do_proto; 835 875 }
Note:
See TracChangeset
for help on using the changeset viewer.