s4:rpc_server: move dcesrv_alter_resp
[sfrench/samba-autobuild/.git] / source4 / libcli / clilist.c
index 84d96d62f44865b0136b2d93f6225f9a8a4b7b30..2fa4112200e2accb7ab74d2601ed983579a99a87 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "libcli/libcli.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
 
 struct search_private {
-       file_info *dirlist;
+       struct clilist_file_info *dirlist;
        TALLOC_CTX *mem_ctx;
        int dirlist_len;
        int ff_searchcount;  /* total received in 1 server trip */
        int total_received;  /* total received all together */
-       enum smb_search_level info_level;
+       enum smb_search_data_level data_level;
        const char *last_name;     /* used to continue trans2 search */
        struct smb_search_id id;   /* used for old-style search */
 };
@@ -36,86 +38,80 @@ struct search_private {
 /****************************************************************************
  Interpret a long filename structure.
 ****************************************************************************/
-static BOOL interpret_long_filename(enum smb_search_level level,
-                                   union smb_search_data *info,
-                                   file_info *finfo)
+static bool interpret_long_filename(enum smb_search_data_level level,
+                                   const union smb_search_data *info,
+                                   struct clilist_file_info *finfo)
 {
-       file_info finfo2;
+       struct clilist_file_info finfo2;
 
        if (!finfo) finfo = &finfo2;
        ZERO_STRUCTP(finfo);
 
        switch (level) {
-       case RAW_SEARCH_STANDARD:
+       case RAW_SEARCH_DATA_STANDARD:
                finfo->size = info->standard.size;
-               finfo->ctime = info->standard.create_time;
-               finfo->atime = info->standard.access_time;
                finfo->mtime = info->standard.write_time;
-               finfo->mode = info->standard.attrib;
+               finfo->attrib = info->standard.attrib;
                finfo->name = info->standard.name.s;
+               finfo->short_name = info->standard.name.s;
                break;
 
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
                finfo->size = info->both_directory_info.size;
-               finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time);
-               finfo->atime = nt_time_to_unix(info->both_directory_info.access_time);
                finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time);
-               finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */
-               if (info->both_directory_info.short_name.s) {
-                       strncpy(finfo->short_name, info->both_directory_info.short_name.s, 
-                               sizeof(finfo->short_name)-1);
-               }
+               finfo->attrib = info->both_directory_info.attrib;
+               finfo->short_name = info->both_directory_info.short_name.s;
                finfo->name = info->both_directory_info.name.s;
                break;
 
        default:
                DEBUG(0,("Unhandled level %d in interpret_long_filename\n", (int)level));
-               return False;
+               return false;
        }
 
-       return True;
+       return true;
 }
 
 /* callback function used for trans2 search */
-static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file)
+static bool smbcli_list_new_callback(void *private_data, const union smb_search_data *file)
 {
-       struct search_private *state = (struct search_private*) private;
-       file_info *tdl;
+       struct search_private *state = (struct search_private*) private_data;
+       struct clilist_file_info *tdl;
  
        /* add file info to the dirlist pool */
        tdl = talloc_realloc(state, 
                             state->dirlist,
-                            state->dirlist_len + sizeof(struct file_info));
-
+                            struct clilist_file_info,
+                            state->dirlist_len + 1);
        if (!tdl) {
-               return False;
+               return false;
        }
        state->dirlist = tdl;
-       state->dirlist_len += sizeof(struct file_info);
+       state->dirlist_len++;
 
-       interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]);
+       interpret_long_filename(state->data_level, file, &state->dirlist[state->total_received]);
 
        state->last_name = state->dirlist[state->total_received].name;
        state->total_received++;
        state->ff_searchcount++;
        
-       return True;
+       return true;
 }
 
 int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, 
-                   enum smb_search_level level,
-                   void (*fn)(file_info *, const char *, void *), 
+                   enum smb_search_data_level level,
+                   void (*fn)(struct clilist_file_info *, const char *, void *), 
                    void *caller_state)
 {
        union smb_search_first first_parms;
        union smb_search_next next_parms;
        struct search_private state;  /* for callbacks */
        int received = 0;
-       BOOL first = True;
+       bool first = true;
        int num_received = 0;
        int max_matches = 512;
        char *mask;
-       int ff_eos = 0, i, ff_searchcount;
+       int ff_eos = 0, i;
        int ff_dir_handle=0;
 
        /* initialize state for search */
@@ -123,24 +119,26 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
        state.dirlist_len = 0;
        state.total_received = 0;
        
-       state.dirlist = talloc(state.mem_ctx, 0);
+       state.dirlist = talloc_array(state.mem_ctx, 
+                                    struct clilist_file_info, 0);
        mask = talloc_strdup(state.mem_ctx, Mask);
 
-       if (level == RAW_SEARCH_GENERIC) {
+       if (level == RAW_SEARCH_DATA_GENERIC) {
                if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) {
-                       level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+                       level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
                } else {
-                       level = RAW_SEARCH_STANDARD;
+                       level = RAW_SEARCH_DATA_STANDARD;
                }
        }
-       state.info_level = level;
+       state.data_level = level;
 
        while (1) {
                state.ff_searchcount = 0;
                if (first) {
                        NTSTATUS status;
 
-                       first_parms.t2ffirst.level = state.info_level;
+                       first_parms.t2ffirst.level = RAW_SEARCH_TRANS2;
+                       first_parms.t2ffirst.data_level = state.data_level;
                        first_parms.t2ffirst.in.max_count = max_matches;
                        first_parms.t2ffirst.in.search_attrib = attribute;
                        first_parms.t2ffirst.in.pattern = mask;
@@ -151,22 +149,22 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                                                      state.mem_ctx, &first_parms,
                                                      (void*)&state, smbcli_list_new_callback);
                        if (!NT_STATUS_IS_OK(status)) {
-                               talloc_destroy(state.mem_ctx);
+                               talloc_free(state.mem_ctx);
                                return -1;
                        }
                
                        ff_dir_handle = first_parms.t2ffirst.out.handle;
-                       ff_searchcount = first_parms.t2ffirst.out.count;
                        ff_eos = first_parms.t2ffirst.out.end_of_search;
                        
                        received = first_parms.t2ffirst.out.count;
                        if (received <= 0) break;
                        if (ff_eos) break;
-                       first = False;
+                       first = false;
                } else {
                        NTSTATUS status;
 
-                       next_parms.t2fnext.level = state.info_level;
+                       next_parms.t2fnext.level = RAW_SEARCH_TRANS2;
+                       next_parms.t2fnext.data_level = state.data_level;
                        next_parms.t2fnext.in.max_count = max_matches;
                        next_parms.t2fnext.in.last_name = state.last_name;
                        next_parms.t2fnext.in.handle = ff_dir_handle;
@@ -182,7 +180,6 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                        if (!NT_STATUS_IS_OK(status)) {
                                return -1;
                        }
-                       ff_searchcount = next_parms.t2fnext.out.count;
                        ff_eos = next_parms.t2fnext.out.end_of_search;
                        received = next_parms.t2fnext.out.count;
                        if (received <= 0) break;
@@ -196,7 +193,7 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                fn(&state.dirlist[i], Mask, caller_state);
        }
 
-       talloc_destroy(state.mem_ctx);
+       talloc_free(state.mem_ctx);
 
        return state.total_received;
 }
@@ -205,52 +202,61 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
  Interpret a short filename structure.
  The length of the structure is returned.
 ****************************************************************************/
-static BOOL interpret_short_filename(int level,
-                               union smb_search_data *info,
-                               file_info *finfo)
+static bool interpret_short_filename(enum smb_search_data_level level,
+                                    const union smb_search_data *info,
+                                    struct clilist_file_info *finfo)
 {
-       file_info finfo2;
+       struct clilist_file_info finfo2;
 
        if (!finfo) finfo = &finfo2;
        ZERO_STRUCTP(finfo);
+
+       switch (level) {
+       case RAW_SEARCH_DATA_SEARCH:
+               finfo->mtime = info->search.write_time;
+               finfo->size = info->search.size;
+               finfo->attrib = info->search.attrib;
+               finfo->name = info->search.name;
+               finfo->short_name = info->search.name;
+               break;
+
+       default:
+               DEBUG(0,("Unhandled level %d in interpret_short_filename\n", (int)level));
+               return false;
+       }
        
-       finfo->ctime = info->search.write_time;
-       finfo->atime = info->search.write_time;
-       finfo->mtime = info->search.write_time;
-       finfo->size = info->search.size;
-       finfo->mode = info->search.attrib;
-       finfo->name = info->search.name;
-       return True;
+       return true;
 }
 
 /* callback function used for smb_search */
-static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file)
+static bool smbcli_list_old_callback(void *private_data, const union smb_search_data *file)
 {
-       struct search_private *state = (struct search_private*) private;
-       file_info *tdl;
+       struct search_private *state = (struct search_private*) private_data;
+       struct clilist_file_info *tdl;
        
        /* add file info to the dirlist pool */
        tdl = talloc_realloc(state,
                             state->dirlist,
-                            state->dirlist_len + sizeof(struct file_info));
+                            struct clilist_file_info,
+                            state->dirlist_len + 1);
 
        if (!tdl) {
-               return False;
+               return false;
        }
        state->dirlist = tdl;
-       state->dirlist_len += sizeof(struct file_info);
+       state->dirlist_len++;
 
-       interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]);
+       interpret_short_filename(state->data_level, file, &state->dirlist[state->total_received]);
 
        state->total_received++;
        state->ff_searchcount++;
        state->id = file->search.id; /* return resume info */
        
-       return True;
+       return true;
 }
 
 int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, 
-                void (*fn)(file_info *, const char *, void *), 
+                void (*fn)(struct clilist_file_info *, const char *, void *), 
                 void *caller_state)
 {
        union smb_search_first first_parms;
@@ -258,7 +264,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
        struct search_private state;  /* for callbacks */
        const int num_asked = 500;
        int received = 0;
-       BOOL first = True;
+       bool first = true;
        int num_received = 0;
        char *mask;
        int i;
@@ -267,8 +273,10 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
        state.mem_ctx = talloc_init("smbcli_list_old");
        state.dirlist_len = 0;
        state.total_received = 0;
+       state.data_level = RAW_SEARCH_DATA_SEARCH;
 
-       state.dirlist = talloc(state.mem_ctx, 0);
+       state.dirlist = talloc_array(state.mem_ctx, struct clilist_file_info,
+                                    0);
        mask = talloc_strdup(state.mem_ctx, Mask);
   
        while (1) {
@@ -277,6 +285,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                        NTSTATUS status;
 
                        first_parms.search_first.level = RAW_SEARCH_SEARCH;
+                       first_parms.search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                        first_parms.search_first.in.max_count = num_asked;
                        first_parms.search_first.in.search_attrib = attribute;
                        first_parms.search_first.in.pattern = mask;
@@ -287,17 +296,18 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                                                      smbcli_list_old_callback);
 
                        if (!NT_STATUS_IS_OK(status)) {
-                               talloc_destroy(state.mem_ctx);
+                               talloc_free(state.mem_ctx);
                                return -1;
                        }
                
                        received = first_parms.search_first.out.count;
                        if (received <= 0) break;
-                       first = False;
+                       first = false;
                } else {
                        NTSTATUS status;
 
                        next_parms.search_next.level = RAW_SEARCH_SEARCH;
+                       next_parms.search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                        next_parms.search_next.in.max_count = num_asked;
                        next_parms.search_next.in.search_attrib = attribute;
                        next_parms.search_next.in.id = state.id;
@@ -311,7 +321,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                                break;
                        }
                        if (!NT_STATUS_IS_OK(status)) {
-                               talloc_destroy(state.mem_ctx);
+                               talloc_free(state.mem_ctx);
                                return -1;
                        }
                        received = next_parms.search_next.out.count;
@@ -325,7 +335,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                fn(&state.dirlist[i], Mask, caller_state);
        }
 
-       talloc_destroy(state.mem_ctx);
+       talloc_free(state.mem_ctx);
 
        return state.total_received;
 }
@@ -336,9 +346,9 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
 ****************************************************************************/
 
 int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, 
-            void (*fn)(file_info *, const char *, void *), void *state)
+               void (*fn)(struct clilist_file_info *, const char *, void *), void *state)
 {
        if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1)
                return smbcli_list_old(tree, Mask, attribute, fn, state);
-       return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_GENERIC, fn, state);
+       return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_DATA_GENERIC, fn, state);
 }