I told Jeremy at the CIFS conference that I would sort the command list
[sfrench/samba-autobuild/.git] / source3 / client / client.c
index f759ac7b7607607d489ae5a9478f7003717116e5..448f4314c814040aa74242bf6c4ee68f7aee473e 100644 (file)
@@ -48,7 +48,7 @@ static int max_protocol = PROTOCOL_NT1;
 extern pstring user_socket_options;
 
 static int process_tok(fstring tok);
-static NTSTATUS cmd_help(void);
+static void cmd_help(void);
 
 /* 30 second timeout on most commands */
 #define CLIENT_TIMEOUT (30*1000)
@@ -135,17 +135,17 @@ static int writefile(int f, char *b, int n)
   read from a file with LF->CR/LF translation if appropriate. return the 
   number read. read approx n bytes.
 ****************************************************************************/
-static int readfile(char *b, int size, int n, FILE *f)
+static int readfile(char *b, int n, XFILE *f)
 {
        int i;
        int c;
 
-       if (!translation || (size != 1))
-               return(fread(b,size,n,f));
+       if (!translation)
+               return x_fread(b,1,n,f);
   
        i = 0;
        while (i < (n - 1) && (i < BUFFER_SIZE)) {
-               if ((c = getc(f)) == EOF) {
+               if ((c = x_getc(f)) == EOF) {
                        break;
                }
       
@@ -365,11 +365,7 @@ functions for do_list_queue
  */
 static void reset_do_list_queue(void)
 {
-       if (do_list_queue)
-       {
-               free(do_list_queue);
-       }
-       do_list_queue = 0;
+       SAFE_FREE(do_list_queue);
        do_list_queue_size = 0;
        do_list_queue_start = 0;
        do_list_queue_end = 0;
@@ -707,7 +703,7 @@ static void do_get(char *rname,char *lname)
                rname, (long)nread));
        }
 
-       free(data);
+       SAFE_FREE(data);
        
        if (!cli_close(cli, fnum)) {
                d_printf("Error %s closing remote file\n",cli_errstr(cli));
@@ -981,7 +977,7 @@ static void cmd_mkdir(void)
 static void do_put(char *rname,char *lname)
 {
        int fnum;
-       FILE *f;
+       XFILE *f;
        int nread=0;
        char *buf=NULL;
        int maxwrite=io_bufsize;
@@ -999,10 +995,10 @@ static void do_put(char *rname,char *lname)
        /* allow files to be piped into smbclient
           jdblair 24.jun.98 */
        if (!strcmp(lname, "-")) {
-               f = stdin;
+               f = x_stdin;
                /* size of file is not known */
        } else {
-               f = sys_fopen(lname,"r");
+               f = x_fopen(lname,O_RDONLY, 0);
        }
 
        if (!f) {
@@ -1019,12 +1015,12 @@ static void do_put(char *rname,char *lname)
                d_printf("ERROR: Not enough memory!\n");
                return;
        }
-       while (!feof(f)) {
+       while (!x_feof(f)) {
                int n = maxwrite;
                int ret;
 
-               if ((n = readfile(buf,1,n,f)) < 1) {
-                       if((n == 0) && feof(f))
+               if ((n = readfile(buf,n,f)) < 1) {
+                       if((n == 0) && x_feof(f))
                                break; /* Empty local file. */
 
                        d_printf("Error reading local file: %s\n", strerror(errno));
@@ -1043,14 +1039,14 @@ static void do_put(char *rname,char *lname)
 
        if (!cli_close(cli, fnum)) {
                d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
-               fclose(f);
-               if (buf) free(buf);
+               x_fclose(f);
+               SAFE_FREE(buf);
                return;
        }
 
        
-       fclose(f);
-       if (buf) free(buf);
+       x_fclose(f);
+       SAFE_FREE(buf);
 
        {
                struct timeval tp_end;
@@ -1068,7 +1064,7 @@ static void do_put(char *rname,char *lname)
                         put_total_size / (1.024*put_total_time_ms)));
        }
 
-       if (f == stdin) {
+       if (f == x_stdin) {
                cli_shutdown(cli);
                exit(0);
        }
@@ -1138,8 +1134,8 @@ static void free_file_list (struct file_list * list)
        {
                tmp = list;
                DLIST_REMOVE(list, list);
-               if (tmp->file_path) free(tmp->file_path);
-               free(tmp);
+               SAFE_FREE(tmp->file_path);
+               SAFE_FREE(tmp);
        }
 }
 
@@ -1209,7 +1205,7 @@ static int file_find(struct file_list **list, const char *directory,
                                }
                                
                                if (ret == -1) {
-                                       free(path);
+                                       SAFE_FREE(path);
                                        closedir(dir);
                                        return -1;
                                }
@@ -1224,7 +1220,7 @@ static int file_find(struct file_list **list, const char *directory,
                        entry->isdir = isdir;
                         DLIST_ADD(*list, entry);
                } else {
-                       free(path);
+                       SAFE_FREE(path);
                }
         }
 
@@ -1260,7 +1256,7 @@ static void cmd_mput(void)
                for (temp_list = file_list; temp_list; 
                     temp_list = temp_list->next) {
 
-                       if (lname) free(lname);
+                       SAFE_FREE(lname);
                        if (asprintf(&lname, "%s/", temp_list->file_path) <= 0)
                                continue;
                        trim_string(lname, "./", "/");
@@ -1269,7 +1265,7 @@ static void cmd_mput(void)
                        if (temp_list->isdir) {
                                /* if (!recurse) continue; */
                                
-                               if (quest) free(quest);
+                               SAFE_FREE(quest);
                                asprintf(&quest, "Put directory %s? ", lname);
                                if (prompt && !yesno(quest)) { /* No */
                                        /* Skip the directory */
@@ -1277,7 +1273,7 @@ static void cmd_mput(void)
                                        if (!seek_list(temp_list, lname))
                                                break;              
                                } else { /* Yes */
-                                       if (rname) free(rname);
+                                       SAFE_FREE(rname);
                                        asprintf(&rname, "%s%s", cur_dir, lname);
                                        dos_format(rname);
                                        if (!cli_chkpath(cli, rname) && 
@@ -1291,13 +1287,13 @@ static void cmd_mput(void)
                                }
                                continue;
                        } else {
-                               if (quest) free(quest);
+                               SAFE_FREE(quest);
                                asprintf(&quest,"Put file %s? ", lname);
                                if (prompt && !yesno(quest)) /* No */
                                        continue;
                                
                                /* Yes */
-                               if (rname) free(rname);
+                               SAFE_FREE(rname);
                                asprintf(&rname, "%s%s", cur_dir, lname);
                        }
 
@@ -1306,9 +1302,9 @@ static void cmd_mput(void)
                        do_put(rname, lname);
                }
                free_file_list(file_list);
-               if (quest) free(quest);
-               if (lname) free(lname);
-               if (rname) free(rname);
+               SAFE_FREE(quest);
+               SAFE_FREE(lname);
+               SAFE_FREE(rname);
        }
 }
 
@@ -1699,7 +1695,11 @@ static BOOL list_servers(char *wk_grp)
 #define COMPL_REMOTE      1          /* Complete remote filename */
 #define COMPL_LOCAL       2          /* Complete local filename */
 
-/* This defines the commands supported by this client */
+/* This defines the commands supported by this client.
+ * NOTE: The "!" must be the last one in the list because it's fn pointer
+ *       field is NULL, and NULL in that field is used in process_tok()
+ *       (below) to indicate the end of the list.  crh
+ */
 struct
 {
   char *name;
@@ -1708,47 +1708,46 @@ struct
   char compl_args[2];      /* Completion argument info */
 } commands[] = 
 {
-  {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
+  {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
+  {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
+  {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
+  {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
+  {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
   {"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
   {"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
-  {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
-  {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
-  {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
+  {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
   {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
+  {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
+  {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
+  {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
+  {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},  
+  {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
+  {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
+  {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
   {"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}},
-  {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
-  {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
-  {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
+  {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
   {"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}},  
-  {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
-  {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
+  {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
+  {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
   {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
-  {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
-  {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
-  {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
-  {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
-  {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
-  {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},  
-  {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},  
-  {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},  
-  {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},  
   {"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}},
   {"printmode",cmd_printmode,"<graphics or text> set the print mode",{COMPL_NONE,COMPL_NONE}},
+  {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},  
+  {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
+  {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
+  {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
   {"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
-  {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
   {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
-  {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
-  {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
-  {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
-  {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
-  {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
-  {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
-  {"tarmode",cmd_tarmode,
-     "<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
+  {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
+  {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},  
+  {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
+  {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
+  {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
   {"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
-  {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
+  {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
+  {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
+  {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
   {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
-  {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
   {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
   {"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
 };
@@ -1787,7 +1786,7 @@ static int process_tok(fstring tok)
 /****************************************************************************
 help
 ****************************************************************************/
-static NTSTATUS cmd_help(void)
+static void cmd_help(void)
 {
        int i=0,j;
        fstring buf;
@@ -1804,7 +1803,7 @@ static NTSTATUS cmd_help(void)
                        d_printf("\n");
                }
        }
-       return NT_STATUS_OK;
+       return;
 }
 
 /****************************************************************************
@@ -1872,7 +1871,7 @@ static char **completion_fn(char *text, int start, int end)
        }
 
        if (count == 2) {
-               free(matches[0]);
+               SAFE_FREE(matches[0]);
                matches[0] = strdup(matches[1]);
        }
        matches[count] = NULL;
@@ -2009,7 +2008,7 @@ struct cli_state *do_connect(const char *server, const char *share)
                d_printf("session request to %s failed (%s)\n", 
                         called.name, cli_errstr(c));
                cli_shutdown(c);
-               free(c);
+               SAFE_FREE(c);
                if ((p=strchr_m(called.name, '.'))) {
                        *p = 0;
                        goto again;
@@ -2026,7 +2025,7 @@ struct cli_state *do_connect(const char *server, const char *share)
        if (!cli_negprot(c)) {
                d_printf("protocol negotiation failed\n");
                cli_shutdown(c);
-               free(c);
+               SAFE_FREE(c);
                return NULL;
        }
 
@@ -2046,7 +2045,7 @@ struct cli_state *do_connect(const char *server, const char *share)
                    !cli_session_setup(c, "", "", 0, "", 0, workgroup)) { 
                        d_printf("session setup failed: %s\n", cli_errstr(c));
                        cli_shutdown(c);
-                       free(c);
+                       SAFE_FREE(c);
                        return NULL;
                }
                d_printf("Anonymous login successful\n");
@@ -2071,7 +2070,7 @@ struct cli_state *do_connect(const char *server, const char *share)
                            password, strlen(password)+1)) {
                d_printf("tree connect failed: %s\n", cli_errstr(c));
                cli_shutdown(c);
-               free(c);
+               SAFE_FREE(c);
                return NULL;
        }
 
@@ -2280,7 +2279,6 @@ static int do_message_op(void)
        fstring base_directory;
        char *pname = argv[0];
        int opt;
-       extern FILE *dbf;
        extern char *optarg;
        extern int optind;
        int old_debug;
@@ -2315,7 +2313,7 @@ static int do_message_op(void)
 
        for (opt = 1; opt < argc; opt++) {
                if (strcmp(argv[opt], "-E") == 0)
-                       dbf = stderr;
+                       dbf = x_stderr;
                else if(strncmp(argv[opt], "-s", 2) == 0) {
                        if(argv[opt][2] != '\0')
                                pstrcpy(servicesf, &argv[opt][2]);
@@ -2473,7 +2471,7 @@ static int do_message_op(void)
                        break;
                case 'E':
                        display_set_stderr();
-                       dbf = stderr;
+                       dbf = x_stderr;
                        break;
                case 'U':
                        {
@@ -2490,22 +2488,22 @@ static int do_message_op(void)
 
                case 'A':
                        {
-                               FILE *auth;
+                               XFILE *auth;
                                fstring buf;
                                uint16 len = 0;
                                char *ptr, *val, *param;
                                
-                               if ((auth=sys_fopen(optarg, "r")) == NULL)
+                               if ((auth=x_fopen(optarg, O_RDONLY, 0)) == NULL)
                                {
                                        /* fail if we can't open the credentials file */
                                        d_printf("ERROR: Unable to open credentials file!\n");
                                        exit (-1);
                                }
                                 
-                               while (!feof(auth))
+                               while (!x_feof(auth))
                                {  
                                        /* get a line from the file */
-                                       if (!fgets (buf, sizeof(buf), auth))
+                                       if (!x_fgets(buf, sizeof(buf), auth))
                                                continue;
                                        len = strlen(buf);
                                        
@@ -2539,7 +2537,7 @@ static int do_message_op(void)
                                                
                                        memset(buf, 0, sizeof(buf));
                                }
-                               fclose(auth);
+                               x_fclose(auth);
                        }
                        break;