r7963: Add aio support to 3.0.
[jra/samba/.git] / source3 / smbd / reply.c
index 1c2e950836769a94064e070f8a3b992a613ae70d..312a3ace23cc99925dd7831f6d2883e35a7a796e 100644 (file)
@@ -398,7 +398,9 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
        } else {
                ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
        }
-       if (allow_wcard_names) {
+       if (lp_posix_pathnames()) {
+               *err = check_path_syntax_posix(dest, tmppath);
+       } else if (allow_wcard_names) {
                *err = check_path_syntax_wcard(dest, tmppath);
        } else {
                *err = check_path_syntax(dest, tmppath);
@@ -1012,9 +1014,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        pstring directory;
        pstring fname;
        SMB_OFF_T size;
-       int mode;
+       uint32 mode;
        time_t date;
-       int dirtype;
+       uint32 dirtype;
        int outsize = 0;
        unsigned int numentries = 0;
        unsigned int maxentries = 0;
@@ -1032,6 +1034,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        NTSTATUS nt_status;
        BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
 
+       if (lp_posix_pathnames()) {
+               return reply_unknown(inbuf, outbuf);
+       }
+
        START_PROFILE(SMBsearch);
 
        *mask = *directory = *fname = 0;
@@ -1109,7 +1115,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                ok = True;
      
                if (status_len == 0) {
-                       dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
+                       dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid), mask, dirtype);
                        if (dptr_num < 0) {
                                if(dptr_num == -2) {
                                        END_PROFILE(SMBsearch);
@@ -1118,10 +1124,6 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                                END_PROFILE(SMBsearch);
                                return ERROR_DOS(ERRDOS,ERRnofids);
                        }
-                       if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
-                               END_PROFILE(SMBsearch);
-                               return ERROR_DOS(ERRDOS,ERRnomem);
-                       }
                } else {
                        dirtype = dptr_attr(dptr_num);
                }
@@ -1228,6 +1230,10 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        char *p;
        NTSTATUS err;
 
+       if (lp_posix_pathnames()) {
+               return reply_unknown(inbuf, outbuf);
+       }
+
        START_PROFILE(SMBfclose);
 
        outsize = set_message(outbuf,1,0,True);
@@ -1733,10 +1739,10 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
  Check if a user is allowed to delete a file.
 ********************************************************************/
 
-NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_path, BOOL check_is_at_open)
+NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open)
 {
        SMB_STRUCT_STAT sbuf;
-       int fmode;
+       uint32 fmode;
        int smb_action;
        int access_mode;
        files_struct *fsp;
@@ -1807,7 +1813,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_
  code.
 ****************************************************************************/
 
-NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
+NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype, char *name)
 {
        pstring directory;
        pstring mask;
@@ -1869,8 +1875,11 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
                struct smb_Dir *dir_hnd = NULL;
                const char *dname;
                
+               if (strequal(mask,"????????.???"))
+                       pstrcpy(mask,"*");
+
                if (check_name(directory,conn))
-                       dir_hnd = OpenDir(conn, directory);
+                       dir_hnd = OpenDir(conn, directory, mask, dirtype);
                
                /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
                   the pattern matches against the long name, otherwise the short name 
@@ -1881,9 +1890,6 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
                        long offset = 0;
                        error = NT_STATUS_NO_SUCH_FILE;
 
-                       if (strequal(mask,"????????.???"))
-                               pstrcpy(mask,"*");
-
                        while ((dname = ReadDirName(dir_hnd, &offset))) {
                                SMB_STRUCT_STAT st;
                                pstring fname;
@@ -1944,7 +1950,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 {
        int outsize = 0;
        pstring name;
-       int dirtype;
+       uint32 dirtype;
        NTSTATUS status;
        START_PROFILE(SMBunlink);
        
@@ -2569,6 +2575,11 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                return ERROR_DOS(ERRDOS,ERRlock);
        }
 
+       if (schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) {
+               END_PROFILE(SMBreadX);
+               return -1;
+       }
+
        nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
        if (nread != -1)
                nread = chain_reply(inbuf,outbuf,length,bufsize);
@@ -2642,6 +2653,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
        SCVAL(outbuf,smb_com,SMBwritebraw);
        SSVALS(outbuf,smb_vwv0,-1);
        outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
+       show_msg(outbuf);
        if (!send_smb(smbd_server_fd(),outbuf))
                exit_server("reply_writebraw: send_smb failed.");
   
@@ -2886,9 +2898,12 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
        CHECK_FSP(fsp,conn);
        CHECK_WRITE(fsp);
 
+       set_message(outbuf,6,0,True);
+  
        /* Deal with possible LARGE_WRITEX */
-       if (large_writeX)
+       if (large_writeX) {
                numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
+       }
 
        if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
                END_PROFILE(SMBwriteX);
@@ -2930,18 +2945,24 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
        done, just a write of zero. To truncate a file,
        use SMBwrite. */
 
-       if(numtowrite == 0)
+       if(numtowrite == 0) {
                nwritten = 0;
-       else
+       } else {
+
+               if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize,
+                                       fsp,data,startpos,numtowrite)) {
+                       END_PROFILE(SMBwriteX);
+                       return -1;
+               }
+
                nwritten = write_file(fsp,data,startpos,numtowrite);
+       }
   
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
                END_PROFILE(SMBwriteX);
                return(UNIXERROR(ERRHRD,ERRdiskfull));
        }
 
-       set_message(outbuf,6,0,True);
-  
        SSVAL(outbuf,smb_vwv2,nwritten);
        if (large_writeX)
                SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
@@ -3375,6 +3396,7 @@ int reply_echo(connection_struct *conn,
 
                smb_setlen(outbuf,outsize - 4);
 
+               show_msg(outbuf);
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_echo: send_smb failed.");
        }
@@ -3674,7 +3696,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
        const char *dname = NULL;
        BOOL ret = False;
        long offset = 0;
-       struct smb_Dir *dir_hnd = OpenDir(conn, directory);
+       struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
 
        if(dir_hnd == NULL)
                return True;
@@ -3742,10 +3764,10 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
                 */
                BOOL all_veto_files = True;
                const char *dname;
-               struct smb_Dir *dir_hnd = OpenDir(conn, directory);
+               struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
 
                if(dir_hnd != NULL) {
-                       long dirpos = TellDir(dir_hnd);
+                       long dirpos = 0;
                        while ((dname = ReadDirName(dir_hnd,&dirpos))) {
                                if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
                                        continue;
@@ -3758,7 +3780,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
                        }
 
                        if(all_veto_files) {
-                               SeekDir(dir_hnd,dirpos);
+                               RewindDir(dir_hnd,&dirpos);
                                while ((dname = ReadDirName(dir_hnd,&dirpos))) {
                                        pstring fullname;
 
@@ -3964,7 +3986,7 @@ static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T
  Rename an open file - given an fsp.
 ****************************************************************************/
 
-NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint16 attrs, BOOL replace_if_exists)
+NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint32 attrs, BOOL replace_if_exists)
 {
        SMB_STRUCT_STAT sbuf;
        BOOL bad_path = False;
@@ -4078,7 +4100,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *
  code. 
 ****************************************************************************/
 
-NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists)
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint32 attrs, BOOL replace_if_exists)
 {
        pstring directory;
        pstring mask;
@@ -4300,17 +4322,17 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
                const char *dname;
                pstring destname;
                
+               if (strequal(mask,"????????.???"))
+                       pstrcpy(mask,"*");
+                       
                if (check_name(directory,conn))
-                       dir_hnd = OpenDir(conn, directory);
+                       dir_hnd = OpenDir(conn, directory, mask, attrs);
                
                if (dir_hnd) {
                        long offset = 0;
                        error = NT_STATUS_NO_SUCH_FILE;
 /*                     Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
                        
-                       if (strequal(mask,"????????.???"))
-                               pstrcpy(mask,"*");
-                       
                        while ((dname = ReadDirName(dir_hnd, &offset))) {
                                pstring fname;
                                BOOL sysdir_entry = False;
@@ -4411,7 +4433,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        pstring name;
        pstring newname;
        char *p;
-       uint16 attrs = SVAL(inbuf,smb_vwv0);
+       uint32 attrs = SVAL(inbuf,smb_vwv0);
        NTSTATUS status;
 
        START_PROFILE(SMBmv);
@@ -4459,7 +4481,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
  Copy a file as part of a reply_copy.
 ******************************************************************/
 
-static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
+BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
                      int count,BOOL target_is_directory, int *err_ret)
 {
        int Access,action;
@@ -4656,16 +4678,16 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                const char *dname;
                pstring destname;
 
+               if (strequal(mask,"????????.???"))
+                       pstrcpy(mask,"*");
+
                if (check_name(directory,conn))
-                       dir_hnd = OpenDir(conn, directory);
+                       dir_hnd = OpenDir(conn, directory, mask, 0);
 
                if (dir_hnd) {
                        long offset = 0;
                        error = ERRbadfile;
 
-                       if (strequal(mask,"????????.???"))
-                               pstrcpy(mask,"*");
-
                        while ((dname = ReadDirName(dir_hnd, &offset))) {
                                pstring fname;
                                pstrcpy(fname,dname);
@@ -5173,6 +5195,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
                SSVAL(outbuf,smb_vwv6,nread);
                SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
 
+               show_msg(outbuf);
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_readbmpx: send_smb failed.");
 
@@ -5333,6 +5356,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
        if (write_through && tcount==nwritten) {
                /* We need to send both a primary and a secondary response */
                smb_setlen(outbuf,outsize - 4);
+               show_msg(outbuf);
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_writebmpx: send_smb failed.");