LCOV - code coverage report
Current view: top level - source3/torture - vfstest.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 121 273 44.3 %
Date: 2024-02-28 12:06:22 Functions: 5 15 33.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    VFS module tester
       4             : 
       5             :    Copyright (C) Simo Sorce 2002
       6             :    Copyright (C) Eric Lorimer 2002
       7             :    Copyright (C) Jelmer Vernooij 2002,2003
       8             : 
       9             :    Most of this code was ripped off of rpcclient.
      10             :    Copyright (C) Tim Potter 2000-2001
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "includes.h"
      27             : #include "locking/share_mode_lock.h"
      28             : #include "smbd/smbd.h"
      29             : #include "smbd/globals.h"
      30             : #include "lib/cmdline/cmdline.h"
      31             : #include "vfstest.h"
      32             : #include "../libcli/smbreadline/smbreadline.h"
      33             : #include "auth.h"
      34             : #include "serverid.h"
      35             : #include "messages.h"
      36             : #include "libcli/security/security.h"
      37             : #include "lib/smbd_shim.h"
      38             : #include "system/filesys.h"
      39             : #include "lib/global_contexts.h"
      40             : #include "lib/param/param.h"
      41             : 
      42             : /* List to hold groups of commands */
      43             : static struct cmd_list {
      44             :         struct cmd_list *prev, *next;
      45             :         struct cmd_set *cmd_set;
      46             : } *cmd_list;
      47             : 
      48             : /* shall we do talloc_report after each command? */
      49             : static int memreports = 0;
      50             : 
      51             : /****************************************************************************
      52             : handle completion of commands for readline
      53             : ****************************************************************************/
      54           0 : static char **completion_fn(const char *text, int start, int end)
      55             : {
      56             : #define MAX_COMPLETIONS 100
      57             :         char **matches;
      58           0 :         int i, count=0;
      59           0 :         struct cmd_list *commands = cmd_list;
      60             : 
      61           0 :         if (start)
      62           0 :                 return NULL;
      63             : 
      64             :         /* make sure we have a list of valid commands */
      65           0 :         if (!commands)
      66           0 :                 return NULL;
      67             : 
      68           0 :         matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
      69           0 :         if (!matches) return NULL;
      70             : 
      71           0 :         matches[count++] = SMB_STRDUP(text);
      72           0 :         if (!matches[0]) return NULL;
      73             : 
      74           0 :         while (commands && count < MAX_COMPLETIONS-1)
      75             :         {
      76           0 :                 if (!commands->cmd_set)
      77           0 :                         break;
      78             : 
      79           0 :                 for (i=0; commands->cmd_set[i].name; i++)
      80             :                 {
      81           0 :                         if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
      82           0 :                                 commands->cmd_set[i].fn)
      83             :                         {
      84           0 :                                 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
      85           0 :                                 if (!matches[count])
      86           0 :                                         return NULL;
      87           0 :                                 count++;
      88             :                         }
      89             :                 }
      90             : 
      91           0 :                 commands = commands->next;
      92             :         }
      93             : 
      94           0 :         if (count == 2) {
      95           0 :                 SAFE_FREE(matches[0]);
      96           0 :                 matches[0] = SMB_STRDUP(matches[1]);
      97             :         }
      98           0 :         matches[count] = NULL;
      99           0 :         return matches;
     100             : }
     101             : 
     102           0 : static char *next_command(TALLOC_CTX *ctx, char **cmdstr)
     103             : {
     104             :         char *command;
     105             :         char *p;
     106             : 
     107           0 :         if (!cmdstr || !(*cmdstr))
     108           0 :                 return NULL;
     109             : 
     110           0 :         p = strchr_m(*cmdstr, ';');
     111           0 :         if (p)
     112           0 :                 *p = '\0';
     113           0 :         command = talloc_strdup(ctx, *cmdstr);
     114             : 
     115             :         /* Pass back the remaining cmdstring 
     116             :            (a trailing delimiter ";" does also work),
     117             :            or NULL at last cmdstring.
     118             :         */
     119           0 :         *cmdstr = p ? p + 1 : p;
     120             : 
     121           0 :         return command;
     122             : }
     123             : 
     124             : /* Load specified configuration file */
     125           0 : static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
     126             :                         int argc, const char **argv)
     127             : {
     128           0 :         if (argc != 2) {
     129           0 :                 printf("Usage: %s <smb.conf>\n", argv[0]);
     130           0 :                 return NT_STATUS_OK;
     131             :         }
     132             : 
     133           0 :         if (!lp_load_with_shares(argv[1])) {
     134           0 :                 printf("Error loading \"%s\"\n", argv[1]);
     135           0 :                 return NT_STATUS_OK;
     136             :         }
     137             : 
     138           0 :         printf("\"%s\" successfully loaded\n", argv[1]);
     139           0 :         return NT_STATUS_OK;
     140             : }
     141             : 
     142             : /* Display help on commands */
     143           0 : static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
     144             :                          int argc, const char **argv)
     145             : {
     146             :         struct cmd_list *tmp;
     147             :         struct cmd_set *tmp_set;
     148             : 
     149             :         /* Usage */
     150           0 :         if (argc > 2) {
     151           0 :                 printf("Usage: %s [command]\n", argv[0]);
     152           0 :                 return NT_STATUS_OK;
     153             :         }
     154             : 
     155             :         /* Help on one command */
     156             : 
     157           0 :         if (argc == 2) {
     158           0 :                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
     159             : 
     160           0 :                         tmp_set = tmp->cmd_set;
     161             : 
     162           0 :                         while(tmp_set->name) {
     163           0 :                                 if (strequal(argv[1], tmp_set->name)) {
     164           0 :                                         if (tmp_set->usage &&
     165           0 :                                             tmp_set->usage[0])
     166           0 :                                                 printf("%s\n", tmp_set->usage);
     167             :                                         else
     168           0 :                                                 printf("No help for %s\n", tmp_set->name);
     169             : 
     170           0 :                                         return NT_STATUS_OK;
     171             :                                 }
     172             : 
     173           0 :                                 tmp_set++;
     174             :                         }
     175             :                 }
     176             : 
     177           0 :                 printf("No such command: %s\n", argv[1]);
     178           0 :                 return NT_STATUS_OK;
     179             :         }
     180             : 
     181             :         /* List all commands */
     182             : 
     183           0 :         for (tmp = cmd_list; tmp; tmp = tmp->next) {
     184             : 
     185           0 :                 tmp_set = tmp->cmd_set;
     186             : 
     187           0 :                 while(tmp_set->name) {
     188             : 
     189           0 :                         printf("%15s\t\t%s\n", tmp_set->name,
     190           0 :                                tmp_set->description ? tmp_set->description:
     191             :                                "");
     192             : 
     193           0 :                         tmp_set++;
     194             :                 }
     195             :         }
     196             : 
     197           0 :         return NT_STATUS_OK;
     198             : }
     199             : 
     200             : /* Change the debug level */
     201           0 : static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     202             : {
     203           0 :         if (argc > 2) {
     204           0 :                 printf("Usage: %s [debuglevel]\n", argv[0]);
     205           0 :                 return NT_STATUS_OK;
     206             :         }
     207             : 
     208           0 :         if (argc == 2) {
     209           0 :                 struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     210           0 :                 lpcfg_set_cmdline(lp_ctx, "log level", argv[1]);
     211             :         }
     212             : 
     213           0 :         printf("debuglevel is %d\n", DEBUGLEVEL);
     214             : 
     215           0 :         return NT_STATUS_OK;
     216             : }
     217             : 
     218           0 : static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     219             : {
     220             :         /* Cleanup */
     221           0 :         talloc_destroy(mem_ctx);
     222           0 :         mem_ctx = NULL;
     223           0 :         vfs->data = NULL;
     224           0 :         vfs->data_size = 0;
     225           0 :         return NT_STATUS_OK;
     226             : }
     227             : 
     228           0 : static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     229             : {
     230             :         /* Cleanup */
     231           0 :         talloc_destroy(mem_ctx);
     232             : 
     233           0 :         exit(0);
     234             :         return NT_STATUS_OK; /* NOTREACHED */
     235             : }
     236             : 
     237             : static struct cmd_set vfstest_commands[] = {
     238             : 
     239             :         { .name = "GENERAL OPTIONS" },
     240             : 
     241             :         { "conf",     cmd_conf,       "Load smb configuration file", "conf <smb.conf>" },
     242             :         { "help",     cmd_help,       "Get help on commands", "" },
     243             :         { "?",                cmd_help,       "Get help on commands", "" },
     244             :         { "debuglevel", cmd_debuglevel, "Set debug level", "" },
     245             :         { "freemem",  cmd_freemem,    "Free currently allocated buffers", "" },
     246             :         { "exit",     cmd_quit,       "Exit program", "" },
     247             :         { "quit",     cmd_quit,       "Exit program", "" },
     248             : 
     249             :         { .name = NULL }
     250             : };
     251             : 
     252             : static struct cmd_set separator_command[] = {
     253             :         {
     254             :                 .name        = "---------------",
     255             :                 .description = "----------------------"
     256             :         },
     257             :         {
     258             :                 .name = NULL,
     259             :         },
     260             : };
     261             : 
     262             : 
     263             : extern struct cmd_set vfs_commands[];
     264             : static struct cmd_set *vfstest_command_list[] = {
     265             :         vfstest_commands,
     266             :         vfs_commands,
     267             :         NULL
     268             : };
     269             : 
     270          48 : static void add_command_set(struct cmd_set *cmd_set)
     271             : {
     272             :         struct cmd_list *entry;
     273             : 
     274          48 :         if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
     275           0 :                 DEBUG(0, ("out of memory\n"));
     276           0 :                 return;
     277             :         }
     278             : 
     279          48 :         ZERO_STRUCTP(entry);
     280             : 
     281          48 :         entry->cmd_set = cmd_set;
     282          48 :         DLIST_ADD(cmd_list, entry);
     283             : }
     284             : 
     285          62 : static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
     286             : {
     287          62 :         const char *p = cmd;
     288          62 :         const char **argv = NULL;
     289          62 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     290             :         char *buf;
     291          62 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     292          62 :         int argc = 0;
     293             : 
     294             :         /* Count number of arguments first time through the loop then
     295             :            allocate memory and strdup them. */
     296             : 
     297         124 :  again:
     298         404 :         while(next_token_talloc(mem_ctx, &p, &buf, " ")) {
     299         280 :                 if (argv) {
     300         140 :                         argv[argc] = talloc_strdup(argv, buf);
     301             :                 }
     302         280 :                 argc++;
     303             :         }
     304             : 
     305         124 :         if (!argv) {
     306             :                 /* Create argument list */
     307             : 
     308          62 :                 argv = talloc_zero_array(mem_ctx, const char *, argc);
     309          62 :                 if (argv == NULL) {
     310           0 :                         fprintf(stderr, "out of memory\n");
     311           0 :                         result = NT_STATUS_NO_MEMORY;
     312           0 :                         goto done;
     313             :                 }
     314             : 
     315          62 :                 p = cmd;
     316          62 :                 argc = 0;
     317             : 
     318          62 :                 goto again;
     319             :         }
     320             : 
     321             :         /* Call the function */
     322             : 
     323          62 :         if (cmd_entry->fn) {
     324             :                 /* Run command */
     325          62 :                 result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv);
     326             :         } else {
     327           0 :                 fprintf (stderr, "Invalid command\n");
     328           0 :                 goto done;
     329             :         }
     330             : 
     331          62 :  done:
     332             : 
     333             :         /* Cleanup */
     334             : 
     335          62 :         if (argv) {
     336          62 :                 char **_argv = discard_const_p(char *, argv);
     337          62 :                 TALLOC_FREE(_argv);
     338          62 :                 argv = NULL;
     339             :         }
     340             : 
     341          62 :         if (memreports != 0) {
     342           0 :                 talloc_report_full(mem_ctx, stdout);
     343             :         }
     344          62 :         TALLOC_FREE(mem_ctx);
     345          62 :         return result;
     346             : }
     347             : 
     348             : /* Process a command entered at the prompt or as part of -c */
     349          66 : static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd)
     350             : {
     351             :         struct cmd_list *temp_list;
     352          66 :         bool found = False;
     353             :         char *buf;
     354          66 :         const char *p = cmd;
     355          66 :         NTSTATUS result = NT_STATUS_OK;
     356          66 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     357          66 :         int len = 0;
     358             : 
     359          66 :         if (cmd[strlen(cmd) - 1] == '\n')
     360          66 :                 cmd[strlen(cmd) - 1] = '\0';
     361             : 
     362          66 :         if (!next_token_talloc(mem_ctx, &p, &buf, " ")) {
     363           2 :                 TALLOC_FREE(mem_ctx);
     364           2 :                 return NT_STATUS_OK;
     365             :         }
     366             : 
     367             :         /* Strip the trailing \n if it exists */
     368          64 :         len = strlen(buf);
     369          64 :         if (buf[len-1] == '\n')
     370           0 :                 buf[len-1] = '\0';
     371             : 
     372             :         /* Search for matching commands */
     373             : 
     374         134 :         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
     375         132 :                 struct cmd_set *temp_set = temp_list->cmd_set;
     376             : 
     377        1926 :                 while(temp_set->name) {
     378        1856 :                         if (strequal(buf, temp_set->name)) {
     379          62 :                                 found = True;
     380          62 :                                 result = do_cmd(vfs, temp_set, cmd);
     381             : 
     382          62 :                                 goto done;
     383             :                         }
     384        1794 :                         temp_set++;
     385             :                 }
     386             :         }
     387             : 
     388           2 :  done:
     389          64 :         if (!found && buf[0]) {
     390           2 :                 printf("command not found: %s\n", buf);
     391           2 :                 TALLOC_FREE(mem_ctx);
     392           2 :                 return NT_STATUS_OK;
     393             :         }
     394             : 
     395          62 :         if (!NT_STATUS_IS_OK(result)) {
     396           6 :                 printf("result was %s\n", nt_errstr(result));
     397             :         }
     398             : 
     399          62 :         TALLOC_FREE(mem_ctx);
     400          62 :         return result;
     401             : }
     402             : 
     403          12 : static void process_file(struct vfs_state *pvfs, char *filename) {
     404             :         FILE *file;
     405             :         char command[3 * PATH_MAX];
     406             : 
     407          12 :         if (*filename == '-') {
     408           0 :                 file = stdin;
     409             :         } else {
     410          12 :                 file = fopen(filename, "r");
     411          12 :                 if (file == NULL) {
     412           0 :                         printf("vfstest: error reading file (%s)!", filename);
     413           0 :                         printf("errno n.%d: %s", errno, strerror(errno));
     414           0 :                         exit(-1);
     415             :                 }
     416             :         }
     417             : 
     418          78 :         while (fgets(command, 3 * PATH_MAX, file) != NULL) {
     419          66 :                 process_cmd(pvfs, command);
     420             :         }
     421             : 
     422          12 :         if (file != stdin) {
     423          12 :                 fclose(file);
     424             :         }
     425          12 : }
     426             : 
     427             : static void vfstest_exit_server(const char * const reason) _NORETURN_;
     428           0 : static void vfstest_exit_server(const char * const reason)
     429             : {
     430           0 :         DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
     431           0 :         exit(0);
     432             : }
     433             : 
     434             : static void vfstest_exit_server_cleanly(const char * const reason) _NORETURN_;
     435           0 : static void vfstest_exit_server_cleanly(const char * const reason)
     436             : {
     437           0 :         vfstest_exit_server("normal exit");
     438             : }
     439             : 
     440           0 : struct smb_request *vfstest_get_smbreq(TALLOC_CTX *mem_ctx,
     441             :                                        struct vfs_state *vfs)
     442             : {
     443             :         struct smb_request *result;
     444             :         uint8_t *inbuf;
     445             : 
     446           0 :         result = talloc_zero(mem_ctx, struct smb_request);
     447           0 :         if (result == NULL) {
     448           0 :                 return NULL;
     449             :         }
     450           0 :         result->sconn = vfs->conn->sconn;
     451           0 :         result->mid = ++vfs->mid;
     452             : 
     453           0 :         inbuf = talloc_array(result, uint8_t, smb_size);
     454           0 :         if (inbuf == NULL) {
     455           0 :                 goto fail;
     456             :         }
     457           0 :         SSVAL(inbuf, smb_mid, result->mid);
     458           0 :         smb_setlen(inbuf, smb_size-4);
     459           0 :         result->inbuf = inbuf;
     460           0 :         return result;
     461           0 : fail:
     462           0 :         TALLOC_FREE(result);
     463           0 :         return NULL;
     464             : }
     465             : 
     466             : /* Main function */
     467             : 
     468          12 : int main(int argc, const char *argv[])
     469             : {
     470          12 :         char *cmdstr = NULL;
     471             :         struct cmd_set  **cmd_set;
     472          12 :         struct conn_struct_tos *c = NULL;
     473             :         struct vfs_state *vfs;
     474             :         int opt;
     475             :         int i;
     476          12 :         char *filename = NULL;
     477          12 :         char *cwd = NULL;
     478          12 :         TALLOC_CTX *frame = talloc_stackframe();
     479          12 :         struct auth_session_info *session_info = NULL;
     480          12 :         NTSTATUS status = NT_STATUS_OK;
     481             :         bool ok;
     482             : 
     483             :         /* make sure the vars that get altered (4th field) are in
     484             :            a fixed location or certain compilers complain */
     485             :         poptContext pc;
     486          36 :         struct poptOption long_options[] = {
     487             :                 POPT_AUTOHELP
     488             :                 {
     489             :                         .longName   = "file",
     490             :                         .shortName  = 'f',
     491             :                         .argInfo    = POPT_ARG_STRING,
     492             :                         .arg        = &filename,
     493             :                 },
     494             :                 {
     495             :                         .longName   = "command",
     496             :                         .shortName  = 'c',
     497             :                         .argInfo    = POPT_ARG_STRING,
     498             :                         .arg        = &cmdstr,
     499             :                         .val        = 0,
     500             :                         .descrip    = "Execute specified list of commands",
     501             :                 },
     502             :                 {
     503             :                         .longName   = "memreport",
     504             :                         .shortName  = 'm',
     505             :                         .argInfo    = POPT_ARG_INT,
     506             :                         .arg        = &memreports,
     507             :                         .descrip    = "Report memory left on talloc stackframe after each command",
     508             :                 },
     509          12 :                 POPT_COMMON_SAMBA
     510          12 :                 POPT_COMMON_VERSION
     511             :                 POPT_TABLEEND
     512             :         };
     513             :         static const struct smbd_shim vfstest_shim_fns =
     514             :         {
     515             :                 .exit_server = vfstest_exit_server,
     516             :                 .exit_server_cleanly = vfstest_exit_server_cleanly,
     517             :         };
     518             : 
     519          12 :         smb_init_locale();
     520             : 
     521          12 :         setlinebuf(stdout);
     522             : 
     523          12 :         ok = samba_cmdline_init(frame,
     524             :                                 SAMBA_CMDLINE_CONFIG_SERVER,
     525             :                                 true /* require_smbconf */);
     526          12 :         if (!ok) {
     527           0 :                 TALLOC_FREE(frame);
     528           0 :                 exit(1);
     529             :         }
     530             : 
     531          12 :         pc = samba_popt_get_context("vfstest", argc, argv, long_options, 0);
     532          12 :         if (pc == NULL) {
     533           0 :                 TALLOC_FREE(frame);
     534           0 :                 exit(1);
     535             :         }
     536             : 
     537          12 :         while ((opt = poptGetNextOpt(pc)) != -1) {
     538           0 :                 switch (opt) {
     539           0 :                 case POPT_ERROR_BADOPT:
     540           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
     541             :                                 poptBadOption(pc, 0), poptStrerror(opt));
     542           0 :                         poptPrintUsage(pc, stderr, 0);
     543           0 :                         exit(1);
     544             :                 }
     545             :         }
     546             : 
     547          12 :         poptFreeContext(pc);
     548             : 
     549             :         /* we want total control over the permissions on created files,
     550             :            so set our umask to 0 */
     551          12 :         umask(0);
     552             : 
     553             :         /* TODO: check output */
     554          12 :         reload_services(NULL, NULL, false);
     555             : 
     556          12 :         per_thread_cwd_check();
     557             : 
     558          12 :         set_smbd_shim(&vfstest_shim_fns);
     559             : 
     560             :         /* Load command lists */
     561             : 
     562          12 :         cmd_set = vfstest_command_list;
     563             : 
     564          36 :         while(*cmd_set) {
     565          24 :                 add_command_set(*cmd_set);
     566          24 :                 add_command_set(separator_command);
     567          24 :                 cmd_set++;
     568             :         }
     569             : 
     570             :         /* some basic initialization stuff */
     571          12 :         sec_init();
     572          12 :         init_guest_session_info(frame);
     573          12 :         locking_init();
     574          12 :         vfs = talloc_zero(frame, struct vfs_state);
     575          12 :         if (vfs == NULL) {
     576           0 :                 return 1;
     577             :         }
     578          12 :         status = make_session_info_guest(vfs, &session_info);
     579          12 :         if (!NT_STATUS_IS_OK(status)) {
     580           0 :                 return 1;
     581             :         }
     582             : 
     583             :         /* Provided by libreplace if not present. Always mallocs. */
     584          12 :         cwd = get_current_dir_name();
     585          12 :         if (cwd == NULL) {
     586           0 :                 return -1;
     587             :         }
     588             : 
     589          12 :         status = create_conn_struct_tos_cwd(global_messaging_context(),
     590             :                                         -1,
     591             :                                         cwd,
     592             :                                         session_info,
     593             :                                         &c);
     594          12 :         SAFE_FREE(cwd);
     595          12 :         if (!NT_STATUS_IS_OK(status)) {
     596           0 :                 return 1;
     597             :         }
     598          12 :         vfs->conn = c->conn;
     599             : 
     600          12 :         vfs->conn->share_access = FILE_GENERIC_ALL;
     601          12 :         vfs->conn->read_only = false;
     602             : 
     603          12 :         file_init(vfs->conn->sconn);
     604       12300 :         for (i=0; i < 1024; i++)
     605       12288 :                 vfs->files[i] = NULL;
     606             : 
     607          12 :         if (!posix_locking_init(false)) {
     608           0 :                 return 1;
     609             :         }
     610             : 
     611             :         /* Do we have a file input? */
     612          12 :         if (filename && filename[0]) {
     613          12 :                 process_file(vfs, filename);
     614          12 :                 return 0;
     615             :         }
     616             : 
     617             :         /* Do anything specified with -c */
     618           0 :         if (cmdstr && cmdstr[0]) {
     619             :                 char    *cmd;
     620           0 :                 char    *p = cmdstr;
     621             : 
     622           0 :                 while((cmd=next_command(frame, &p)) != NULL) {
     623           0 :                         status = process_cmd(vfs, cmd);
     624             :                 }
     625             : 
     626           0 :                 TALLOC_FREE(cmd);
     627           0 :                 return NT_STATUS_IS_OK(status) ? 0 : 1;
     628             :         }
     629             : 
     630             :         /* Loop around accepting commands */
     631             : 
     632           0 :         while(1) {
     633           0 :                 char *line = NULL;
     634             : 
     635           0 :                 line = smb_readline("vfstest $> ", NULL, completion_fn);
     636             : 
     637           0 :                 if (line == NULL) {
     638           0 :                         break;
     639             :                 }
     640             : 
     641           0 :                 if (line[0] != '\n') {
     642           0 :                         status = process_cmd(vfs, line);
     643             :                 }
     644           0 :                 SAFE_FREE(line);
     645             :         }
     646             : 
     647           0 :         TALLOC_FREE(vfs);
     648           0 :         TALLOC_FREE(frame);
     649           0 :         return NT_STATUS_IS_OK(status) ? 0 : 1;
     650             : }

Generated by: LCOV version 1.14