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

Generated by: LCOV version 1.13