torture/vfstest.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    VFS module tester
00004 
00005    Copyright (C) Simo Sorce 2002
00006    Copyright (C) Eric Lorimer 2002
00007    Copyright (C) Jelmer Vernooij 2002,2003
00008 
00009    Most of this code was ripped off of rpcclient.
00010    Copyright (C) Tim Potter 2000-2001
00011 
00012    This program is free software; you can redistribute it and/or modify
00013    it under the terms of the GNU General Public License as published by
00014    the Free Software Foundation; either version 2 of the License, or
00015    (at your option) any later version.
00016    
00017    This program is distributed in the hope that it will be useful,
00018    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020    GNU General Public License for more details.
00021    
00022    You should have received a copy of the GNU General Public License
00023    along with this program; if not, write to the Free Software
00024    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025 */
00026 
00027 #include "includes.h"
00028 #include "vfstest.h"
00029 
00030 /* List to hold groups of commands */
00031 static struct cmd_list {
00032         struct cmd_list *prev, *next;
00033         struct cmd_set *cmd_set;
00034 } *cmd_list;
00035 
00036 extern pstring user_socket_options;
00037 
00038 /****************************************************************************
00039 handle completion of commands for readline
00040 ****************************************************************************/
00041 static char **completion_fn(const char *text, int start, int end)
00042 {
00043 #define MAX_COMPLETIONS 100
00044         char **matches;
00045         int i, count=0;
00046         struct cmd_list *commands = cmd_list;
00047 
00048         if (start) 
00049                 return NULL;
00050 
00051         /* make sure we have a list of valid commands */
00052         if (!commands) 
00053                 return NULL;
00054 
00055         matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
00056         if (!matches) return NULL;
00057 
00058         matches[count++] = SMB_STRDUP(text);
00059         if (!matches[0]) return NULL;
00060 
00061         while (commands && count < MAX_COMPLETIONS-1) 
00062         {
00063                 if (!commands->cmd_set)
00064                         break;
00065                 
00066                 for (i=0; commands->cmd_set[i].name; i++)
00067                 {
00068                         if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
00069                                 commands->cmd_set[i].fn) 
00070                         {
00071                                 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
00072                                 if (!matches[count]) 
00073                                         return NULL;
00074                                 count++;
00075                         }
00076                 }
00077                 
00078                 commands = commands->next;
00079                 
00080         }
00081 
00082         if (count == 2) {
00083                 SAFE_FREE(matches[0]);
00084                 matches[0] = SMB_STRDUP(matches[1]);
00085         }
00086         matches[count] = NULL;
00087         return matches;
00088 }
00089 
00090 static char* next_command(char** cmdstr)
00091 {
00092         static pstring          command;
00093         char                    *p;
00094         
00095         if (!cmdstr || !(*cmdstr))
00096                 return NULL;
00097         
00098         p = strchr_m(*cmdstr, ';');
00099         if (p)
00100                 *p = '\0';
00101         pstrcpy(command, *cmdstr);
00102         *cmdstr = p;
00103         
00104         return command;
00105 }
00106 
00107 /* Load specified configuration file */
00108 static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
00109                         int argc, const char **argv)
00110 {
00111         if (argc != 2) {
00112                 printf("Usage: %s <smb.conf>\n", argv[0]);
00113                 return NT_STATUS_OK;
00114         }
00115 
00116         if (!lp_load(argv[1], False, True, False, True)) {
00117                 printf("Error loading \"%s\"\n", argv[1]);
00118                 return NT_STATUS_OK;
00119         }
00120 
00121         printf("\"%s\" successfully loaded\n", argv[1]);
00122         return NT_STATUS_OK;
00123 }
00124         
00125 /* Display help on commands */
00126 static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
00127                          int argc, const char **argv)
00128 {
00129         struct cmd_list *tmp;
00130         struct cmd_set *tmp_set;
00131 
00132         /* Usage */
00133         if (argc > 2) {
00134                 printf("Usage: %s [command]\n", argv[0]);
00135                 return NT_STATUS_OK;
00136         }
00137 
00138         /* Help on one command */
00139 
00140         if (argc == 2) {
00141                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
00142                         
00143                         tmp_set = tmp->cmd_set;
00144 
00145                         while(tmp_set->name) {
00146                                 if (strequal(argv[1], tmp_set->name)) {
00147                                         if (tmp_set->usage &&
00148                                             tmp_set->usage[0])
00149                                                 printf("%s\n", tmp_set->usage);
00150                                         else
00151                                                 printf("No help for %s\n", tmp_set->name);
00152 
00153                                         return NT_STATUS_OK;
00154                                 }
00155 
00156                                 tmp_set++;
00157                         }
00158                 }
00159 
00160                 printf("No such command: %s\n", argv[1]);
00161                 return NT_STATUS_OK;
00162         }
00163 
00164         /* List all commands */
00165 
00166         for (tmp = cmd_list; tmp; tmp = tmp->next) {
00167 
00168                 tmp_set = tmp->cmd_set;
00169 
00170                 while(tmp_set->name) {
00171 
00172                         printf("%15s\t\t%s\n", tmp_set->name,
00173                                tmp_set->description ? tmp_set->description:
00174                                "");
00175 
00176                         tmp_set++;
00177                 }
00178         }
00179 
00180         return NT_STATUS_OK;
00181 }
00182 
00183 /* Change the debug level */
00184 static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
00185 {
00186         if (argc > 2) {
00187                 printf("Usage: %s [debuglevel]\n", argv[0]);
00188                 return NT_STATUS_OK;
00189         }
00190 
00191         if (argc == 2) {
00192                 DEBUGLEVEL = atoi(argv[1]);
00193         }
00194 
00195         printf("debuglevel is %d\n", DEBUGLEVEL);
00196 
00197         return NT_STATUS_OK;
00198 }
00199 
00200 static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
00201 {
00202         /* Cleanup */
00203         talloc_destroy(mem_ctx);
00204         mem_ctx = NULL;
00205         vfs->data = NULL;
00206         vfs->data_size = 0;
00207         return NT_STATUS_OK;
00208 }
00209 
00210 static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
00211 {
00212         /* Cleanup */
00213         talloc_destroy(mem_ctx);
00214 
00215         exit(0);
00216         return NT_STATUS_OK; /* NOTREACHED */
00217 }
00218 
00219 static struct cmd_set vfstest_commands[] = {
00220 
00221         { "GENERAL OPTIONS" },
00222 
00223         { "conf",       cmd_conf,       "Load smb configuration file", "conf <smb.conf>" },
00224         { "help",       cmd_help,       "Get help on commands", "" },
00225         { "?",          cmd_help,       "Get help on commands", "" },
00226         { "debuglevel", cmd_debuglevel, "Set debug level", "" },
00227         { "freemem",    cmd_freemem,    "Free currently allocated buffers", "" },
00228         { "exit",       cmd_quit,       "Exit program", "" },
00229         { "quit",       cmd_quit,       "Exit program", "" },
00230 
00231         { NULL }
00232 };
00233 
00234 static struct cmd_set separator_command[] = {
00235         { "---------------", NULL,      "----------------------" },
00236         { NULL }
00237 };
00238 
00239 
00240 extern struct cmd_set vfs_commands[];
00241 static struct cmd_set *vfstest_command_list[] = {
00242         vfstest_commands,
00243         vfs_commands,
00244         NULL
00245 };
00246 
00247 static void add_command_set(struct cmd_set *cmd_set)
00248 {
00249         struct cmd_list *entry;
00250 
00251         if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
00252                 DEBUG(0, ("out of memory\n"));
00253                 return;
00254         }
00255 
00256         ZERO_STRUCTP(entry);
00257 
00258         entry->cmd_set = cmd_set;
00259         DLIST_ADD(cmd_list, entry);
00260 }
00261 
00262 static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
00263 {
00264         const char *p = cmd;
00265         char **argv = NULL;
00266         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00267         pstring buf;
00268         TALLOC_CTX *mem_ctx = NULL;
00269         int argc = 0, i;
00270 
00271         /* Count number of arguments first time through the loop then
00272            allocate memory and strdup them. */
00273 
00274  again:
00275         while(next_token(&p, buf, " ", sizeof(buf))) {
00276                 if (argv) {
00277                         argv[argc] = SMB_STRDUP(buf);
00278                 }
00279                 
00280                 argc++;
00281         }
00282                                 
00283         if (!argv) {
00284 
00285                 /* Create argument list */
00286 
00287                 argv = SMB_MALLOC_ARRAY(char *, argc);
00288                 memset(argv, 0, sizeof(char *) * argc);
00289 
00290                 if (!argv) {
00291                         fprintf(stderr, "out of memory\n");
00292                         result = NT_STATUS_NO_MEMORY;
00293                         goto done;
00294                 }
00295                                         
00296                 p = cmd;
00297                 argc = 0;
00298                                         
00299                 goto again;
00300         }
00301 
00302         /* Call the function */
00303 
00304         if (cmd_entry->fn) {
00305 
00306                 if (mem_ctx == NULL) {
00307                         /* Create mem_ctx */
00308                         if (!(mem_ctx = talloc_init("do_cmd"))) {
00309                                 DEBUG(0, ("talloc_init() failed\n"));
00310                                 goto done;
00311                         }
00312                 }
00313 
00314                 /* Run command */
00315                 result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv);
00316 
00317         } else {
00318                 fprintf (stderr, "Invalid command\n");
00319                 goto done;
00320         }
00321 
00322  done:
00323                                                 
00324         /* Cleanup */
00325 
00326         if (argv) {
00327                 for (i = 0; i < argc; i++)
00328                         SAFE_FREE(argv[i]);
00329         
00330                 SAFE_FREE(argv);
00331         }
00332         
00333         return result;
00334 }
00335 
00336 /* Process a command entered at the prompt or as part of -c */
00337 static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd)
00338 {
00339         struct cmd_list *temp_list;
00340         BOOL found = False;
00341         pstring buf;
00342         const char *p = cmd;
00343         NTSTATUS result = NT_STATUS_OK;
00344         int len = 0;
00345 
00346         if (cmd[strlen(cmd) - 1] == '\n')
00347                 cmd[strlen(cmd) - 1] = '\0';
00348 
00349         if (!next_token(&p, buf, " ", sizeof(buf))) {
00350                 return NT_STATUS_OK;
00351         }
00352 
00353         /* strip the trainly \n if it exsists */
00354         len = strlen(buf);
00355         if (buf[len-1] == '\n')
00356                 buf[len-1] = '\0';
00357 
00358         /* Search for matching commands */
00359 
00360         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
00361                 struct cmd_set *temp_set = temp_list->cmd_set;
00362 
00363                 while(temp_set->name) {
00364                         if (strequal(buf, temp_set->name)) {
00365                                 found = True;
00366                                 result = do_cmd(vfs, temp_set, cmd);
00367 
00368                                 goto done;
00369                         }
00370                         temp_set++;
00371                 }
00372         }
00373 
00374  done:
00375         if (!found && buf[0]) {
00376                 printf("command not found: %s\n", buf);
00377                 return NT_STATUS_OK;
00378         }
00379 
00380         if (!NT_STATUS_IS_OK(result)) {
00381                 printf("result was %s\n", nt_errstr(result));
00382         }
00383 
00384         return result;
00385 }
00386 
00387 static void process_file(struct vfs_state *pvfs, char *filename) {
00388         FILE *file;
00389         char command[3 * PATH_MAX];
00390 
00391         if (*filename == '-') {
00392                 file = stdin;
00393         } else {
00394                 file = fopen(filename, "r");
00395                 if (file == NULL) {
00396                         printf("vfstest: error reading file (%s)!", filename);
00397                         printf("errno n.%d: %s", errno, strerror(errno));
00398                         exit(-1);
00399                 }
00400         }
00401 
00402         while (fgets(command, 3 * PATH_MAX, file) != NULL) {
00403                 process_cmd(pvfs, command);
00404         }
00405 }
00406 
00407 void exit_server(const char *reason)
00408 {
00409         DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
00410         exit(0);
00411 }
00412 
00413 void exit_server_cleanly(const char *const reason)
00414 {
00415         exit_server("normal exit");
00416 }
00417 
00418 static int server_fd = -1;
00419 int last_message = -1;
00420 
00421 int smbd_server_fd(void)
00422 {
00423                 return server_fd;
00424 }
00425 
00426 void reload_printers(void)
00427 {
00428         return;
00429 }
00430 
00431 /****************************************************************************
00432  Reload the services file.
00433 **************************************************************************/
00434 
00435 BOOL reload_services(BOOL test)
00436 {
00437         BOOL ret;
00438         
00439         if (lp_loaded()) {
00440                 pstring fname;
00441                 pstrcpy(fname,lp_configfile());
00442                 if (file_exist(fname, NULL) &&
00443                     !strcsequal(fname, dyn_CONFIGFILE)) {
00444                         pstrcpy(dyn_CONFIGFILE, fname);
00445                         test = False;
00446                 }
00447         }
00448 
00449         reopen_logs();
00450 
00451         if (test && !lp_file_list_changed())
00452                 return(True);
00453 
00454         lp_killunused(conn_snum_used);
00455         
00456         ret = lp_load(dyn_CONFIGFILE, False, False, True, True);
00457 
00458         /* perhaps the config filename is now set */
00459         if (!test)
00460                 reload_services(True);
00461 
00462         reopen_logs();
00463 
00464         load_interfaces();
00465 
00466         {
00467                 if (smbd_server_fd() != -1) {      
00468                         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
00469                         set_socket_options(smbd_server_fd(), user_socket_options);
00470                 }
00471         }
00472 
00473         mangle_reset_cache();
00474         reset_stat_cache();
00475 
00476         /* this forces service parameters to be flushed */
00477         set_current_service(NULL,0,True);
00478 
00479         return (ret);
00480 }
00481 
00482 struct event_context *smbd_event_context(void)
00483 {
00484         static struct event_context *ctx;
00485 
00486         if (!ctx && !(ctx = event_context_init(NULL))) {
00487                 smb_panic("Could not init smbd event context\n");
00488         }
00489         return ctx;
00490 }
00491 
00492 struct messaging_context *smbd_messaging_context(void)
00493 {
00494         static struct messaging_context *ctx;
00495 
00496         if (!ctx && !(ctx = messaging_init(NULL, server_id_self(),
00497                                            smbd_event_context()))) {
00498                 smb_panic("Could not init smbd messaging context\n");
00499         }
00500         return ctx;
00501 }
00502 
00503 /* Main function */
00504 
00505 int main(int argc, char *argv[])
00506 {
00507         static char             *cmdstr = NULL;
00508         struct cmd_set          **cmd_set;
00509         static struct vfs_state vfs;
00510         int i;
00511         static char             *filename = NULL;
00512 
00513         /* make sure the vars that get altered (4th field) are in
00514            a fixed location or certain compilers complain */
00515         poptContext pc;
00516         struct poptOption long_options[] = {
00517                 POPT_AUTOHELP
00518                 {"file",        'f', POPT_ARG_STRING,   &filename, 0, },
00519                 {"command",     'c', POPT_ARG_STRING,   &cmdstr, 0, "Execute specified list of commands" },
00520                 POPT_COMMON_SAMBA
00521                 POPT_TABLEEND
00522         };
00523 
00524         load_case_tables();
00525 
00526         setlinebuf(stdout);
00527 
00528         pc = poptGetContext("vfstest", argc, (const char **) argv,
00529                             long_options, 0);
00530         
00531         while(poptGetNextOpt(pc) != -1);
00532 
00533 
00534         poptFreeContext(pc);
00535 
00536         /* TODO: check output */
00537         reload_services(False);
00538 
00539         /* the following functions are part of the Samba debugging
00540            facilities.  See lib/debug.c */
00541         setup_logging("vfstest", True);
00542         
00543         /* Load command lists */
00544 
00545         cmd_set = vfstest_command_list;
00546 
00547         while(*cmd_set) {
00548                 add_command_set(*cmd_set);
00549                 add_command_set(separator_command);
00550                 cmd_set++;
00551         }
00552 
00553         /* some basic initialization stuff */
00554         sec_init();
00555         conn_init();
00556         vfs.conn = conn_new();
00557         string_set(&vfs.conn->user,"vfstest");
00558         for (i=0; i < 1024; i++)
00559                 vfs.files[i] = NULL;
00560 
00561         /* some advanced initiliazation stuff */
00562         smbd_vfs_init(vfs.conn);
00563 
00564         /* Do we have a file input? */
00565         if (filename && filename[0]) {
00566                 process_file(&vfs, filename);
00567                 return 0;
00568         }
00569 
00570         /* Do anything specified with -c */
00571         if (cmdstr && cmdstr[0]) {
00572                 char    *cmd;
00573                 char    *p = cmdstr;
00574  
00575                 while((cmd=next_command(&p)) != NULL) {
00576                         process_cmd(&vfs, cmd);
00577                 }
00578                 
00579                 return 0;
00580         }
00581 
00582         /* Loop around accepting commands */
00583 
00584         while(1) {
00585                 pstring prompt;
00586                 char *line;
00587 
00588                 slprintf(prompt, sizeof(prompt) - 1, "vfstest $> ");
00589 
00590                 line = smb_readline(prompt, NULL, completion_fn);
00591 
00592                 if (line == NULL)
00593                         break;
00594 
00595                 if (line[0] != '\n')
00596                         process_cmd(&vfs, line);
00597         }
00598         
00599         conn_free(vfs.conn);
00600         return 0;
00601 }

Sambaに対してSat Aug 29 21:23:28 2009に生成されました。  doxygen 1.4.7