Fix a type-punned warning
[ira/wip.git] / source3 / smbd / reply.c
index e1364f2462027780c40e0d94647d9c2bbdcb0521..1f73b2f40fcf1a5dee9e8e37d8b93649c1f44332 100644 (file)
@@ -477,7 +477,7 @@ static bool netbios_session_retarget(const char *name, int name_type)
                goto fail;
        }
 
-       in_addr = (struct sockaddr_in *)&retarget_addr;
+       in_addr = (struct sockaddr_in *)(void *)&retarget_addr;
 
        _smb_setlen(outbuf, 6);
        SCVAL(outbuf, 0, 0x84);
@@ -2214,7 +2214,7 @@ void reply_ctemp(struct smb_request *req)
                return;
        }
 
-       tmpfd = smb_mkstemp(fname);
+       tmpfd = mkstemp(fname);
        if (tmpfd == -1) {
                reply_unixerror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBctemp);
@@ -2244,7 +2244,7 @@ void reply_ctemp(struct smb_request *req)
                NULL,                                   /* pinfo */
                &sbuf);                                 /* psbuf */
 
-       /* close fd from smb_mkstemp() */
+       /* close fd from mkstemp() */
        close(tmpfd);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -3352,20 +3352,29 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 {
        SMB_STRUCT_STAT sbuf;
        ssize_t nread = -1;
+       struct lock_struct lock;
 
        if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
                reply_unixerror(req, ERRDOS, ERRnoaccess);
                return;
        }
 
-       if (startpos > sbuf.st_size) {
-               smb_maxcnt = 0;
-       } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
-               smb_maxcnt = (sbuf.st_size - startpos);
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+               reply_doserror(req, ERRDOS, ERRlock);
+               return;
        }
 
-       if (smb_maxcnt == 0) {
-               goto normal_read;
+       if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size)
+           || (smb_maxcnt > (sbuf.st_size - startpos))) {
+               /*
+                * We already know that we would do a short read, so don't
+                * try the sendfile() path.
+                */
+               goto nosendfile_read;
        }
 
 #if defined(WITH_SENDFILE)
@@ -3420,8 +3429,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
                                        fsp->fnum, (int)smb_maxcnt, (int)nread ) );
                                /* No outbuf here means successful sendfile. */
-                               TALLOC_FREE(req->outbuf);
-                               return;
+                               goto strict_unlock;
                        }
 
                        DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
@@ -3448,17 +3456,16 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                if (nread != smb_maxcnt + sizeof(headerbuf)) {
                        sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
                }
-
                /* No outbuf here means successful sendfile. */
-               TALLOC_FREE(req->outbuf);
                SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
                SMB_PERFCOUNT_END(&req->pcd);
-               return;
+               goto strict_unlock;
        }
-#endif
 
 normal_read:
 
+#endif
+
        if ((smb_maxcnt & 0xFF0000) > 0x10000) {
                uint8 headerbuf[smb_size + 2*12];
 
@@ -3478,13 +3485,17 @@ normal_read:
                                fsp->fsp_name, strerror(errno) ));
                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
                }
-               TALLOC_FREE(req->outbuf);
-               return;
+               goto strict_unlock;
        }
 
+nosendfile_read:
+
        reply_outbuf(req, 12, smb_maxcnt);
 
        nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        if (nread < 0) {
                reply_unixerror(req, ERRDOS, ERRnoaccess);
                return;
@@ -3496,6 +3507,12 @@ normal_read:
                    fsp->fnum, (int)smb_maxcnt, (int)nread ) );
 
        chain_reply(req);
+       return;
+
+ strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+       TALLOC_FREE(req->outbuf);
+       return;
 }
 
 /****************************************************************************
@@ -3508,7 +3525,6 @@ void reply_read_and_X(struct smb_request *req)
        files_struct *fsp;
        SMB_OFF_T startpos;
        size_t smb_maxcnt;
-       struct lock_struct lock;
        bool big_readX = False;
 #if 0
        size_t smb_mincnt = SVAL(req->vwv+6, 0);
@@ -3597,26 +3613,14 @@ void reply_read_and_X(struct smb_request *req)
 
        }
 
-       init_strict_lock_struct(fsp, (uint32)req->smbpid,
-           (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
-           &lock);
-
-       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
-               END_PROFILE(SMBreadX);
-               reply_doserror(req, ERRDOS, ERRlock);
-               return;
-       }
-
        if (!big_readX &&
            schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
-               goto strict_unlock;
+               goto out;
        }
 
        send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
 
-strict_unlock:
-       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-
+ out:
        END_PROFILE(SMBreadX);
        return;
 }