+ /* Is there an error already? Send pkt and bail out */
+ if (error_pkt_reason || error_pkt_str[0])
+ goto send_err_pkt;
+
+ if (user_opt) {
+ struct passwd *pw = xgetpwnam(user_opt);
+ change_identity(pw); /* initgroups, setgid, setuid */
+ }
+ }
+
+ /* Prepare open mode */
+ if (CMD_PUT(option_mask32)) {
+ open_mode = O_RDONLY;
+ } else {
+ open_mode = O_WRONLY | O_TRUNC | O_CREAT;
+#if ENABLE_TFTPD
+ if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) {
+ /* tftpd without -c */
+ open_mode = O_WRONLY | O_TRUNC;
+ }
+#endif
+ }
+
+ /* Examples of network traffic.
+ * Note two cases when ACKs with block# of 0 are sent.
+ *
+ * Download without options:
+ * tftp -> "\0\1FILENAME\0octet\0"
+ * "\0\3\0\1FILEDATA..." <- tftpd
+ * tftp -> "\0\4\0\1"
+ * ...
+ * Download with option of blksize 16384:
+ * tftp -> "\0\1FILENAME\0octet\0blksize\00016384\0"
+ * "\0\6blksize\00016384\0" <- tftpd
+ * tftp -> "\0\4\0\0"
+ * "\0\3\0\1FILEDATA..." <- tftpd
+ * tftp -> "\0\4\0\1"
+ * ...
+ * Upload without options:
+ * tftp -> "\0\2FILENAME\0octet\0"
+ * "\0\4\0\0" <- tftpd
+ * tftp -> "\0\3\0\1FILEDATA..."
+ * "\0\4\0\1" <- tftpd
+ * ...
+ * Upload with option of blksize 16384:
+ * tftp -> "\0\2FILENAME\0octet\0blksize\00016384\0"
+ * "\0\6blksize\00016384\0" <- tftpd
+ * tftp -> "\0\3\0\1FILEDATA..."
+ * "\0\4\0\1" <- tftpd
+ * ...
+ */
+ block_nr = 1;
+ cp = xbuf + 2;
+
+ if (!ENABLE_TFTP || our_lsa) { /* tftpd */
+ /* Open file (must be after changing user) */
+ local_fd = open(local_file, open_mode, 0666);
+ if (local_fd < 0) {
+ error_pkt_reason = ERR_NOFILE;
+ strcpy((char*)error_pkt_str, "can't open file");
+ goto send_err_pkt;
+ }
+/* gcc 4.3.1 would NOT optimize it out as it should! */