r12608: Remove some unused #include lines.
[abartlet/samba.git/.git] / source4 / scripting / ejs / smbcalls_options.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide a command line options parsing function for ejs
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "lib/cmdline/popt_common.h"
25 #include "scripting/ejs/smbcalls.h"
26
27
28 /*
29   usage:
30       options = GetOptions(argv, 
31                           "realm=s", 
32                           "enablexx", 
33                           "myint=i");
34
35       the special options POPT_COMMON_* options are recognised and replaced
36       with the Samba internal options
37
38       resulting parsed options are placed in the options object
39
40       additional command line arguments are placed in options.ARGV
41 */
42
43 static int ejs_GetOptions(MprVarHandle eid, int argc, struct MprVar **argv)
44 {
45         poptContext pc;
46         int opt;
47         struct {
48                 const char *name;
49                 struct poptOption *table;
50                 const char *description;
51         } tables[] = {
52                 { "POPT_AUTOHELP", poptHelpOptions, "Help options:" },
53                 { "POPT_COMMON_SAMBA", popt_common_samba, "Common Samba options:" },
54                 { "POPT_COMMON_CONNECTION", popt_common_connection, "Connection options:" },
55                 { "POPT_COMMON_CREDENTIALS", popt_common_credentials, "Authentication options:" },
56                 { "POPT_COMMON_VERSION", popt_common_version, "Common Samba options:" }
57         };
58
59         struct MprVar *options = mprInitObject(eid, "options", 0, NULL);
60
61         TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
62         struct poptOption *long_options = NULL;
63         int i, num_options = 0;
64         int opt_argc;
65         const char **opt_argv;
66         const char **opt_names = NULL;
67         const int BASE_OPTNUM = 0x100000;
68
69         /* validate arguments */
70         if (argc < 1 || argv[0]->type != MPR_TYPE_OBJECT) {
71                 ejsSetErrorMsg(eid, "GetOptions invalid arguments");
72                 return -1;
73         }
74
75         opt_argv = mprToArray(tmp_ctx, argv[0]);
76         opt_argc = str_list_length(opt_argv);
77
78         long_options = talloc_array(tmp_ctx, struct poptOption, 1);
79         if (long_options == NULL) {
80                 return -1;
81         }
82
83         /* create the long_options array */
84         for (i=1;i<argc;i++) {
85                 const char *optstr = mprToString(argv[i]);
86                 int t, opt_type = POPT_ARG_NONE;
87                 const char *s;
88                 if (argv[i]->type != MPR_TYPE_STRING) {
89                         ejsSetErrorMsg(eid, "GetOptions string argument");
90                         return -1;
91                 }
92
93                 long_options = talloc_realloc(tmp_ctx, long_options, 
94                                               struct poptOption, num_options+2);
95                 if (long_options == NULL) {
96                         return -1;
97                 }
98                 ZERO_STRUCT(long_options[num_options]);
99
100                 /* see if its one of the special samba option tables */
101                 for (t=0;t<ARRAY_SIZE(tables);t++) {
102                         if (strcmp(tables[t].name, optstr) == 0) {
103                                 break;
104                         }
105                 }
106                 if (t < ARRAY_SIZE(tables)) {
107                         opt_names = str_list_add(opt_names, optstr);
108                         talloc_steal(tmp_ctx, opt_names);
109                         long_options[num_options].argInfo = POPT_ARG_INCLUDE_TABLE;
110                         long_options[num_options].arg     = tables[t].table;
111                         long_options[num_options].descrip = tables[t].description;
112                         num_options++;
113                         continue;
114                 }
115
116                 s = strchr(optstr, '=');
117                 if (s) {
118                         char *name = talloc_strndup(tmp_ctx, optstr, (int)(s-optstr));
119                         opt_names = str_list_add(opt_names, name);
120                         if (s[1] == 's') {
121                                 opt_type = POPT_ARG_STRING;
122                         } else if (s[1] == 'i') {
123                                 opt_type = POPT_ARG_INT;
124                         } else {
125                                 ejsSetErrorMsg(eid, "GetOptions invalid option type");
126                                 return -1;
127                         }
128                         talloc_free(name);
129                 } else {
130                         opt_names = str_list_add(opt_names, optstr);
131                 }
132                 talloc_steal(tmp_ctx, opt_names);
133                 if (strlen(opt_names[num_options]) == 1) {
134                         long_options[num_options].shortName = opt_names[num_options][0];
135                 } else {
136                         long_options[num_options].longName = opt_names[num_options];
137                 }
138                 long_options[num_options].argInfo = opt_type;
139                 long_options[num_options].val = num_options + BASE_OPTNUM;
140                 num_options++;
141         }
142
143         ZERO_STRUCT(long_options[num_options]);
144
145         pc = poptGetContext("smbscript", opt_argc, opt_argv, long_options, 0);
146
147         /* parse the options */
148         while((opt = poptGetNextOpt(pc)) != -1) {
149                 const char *arg;
150
151                 if (opt < BASE_OPTNUM || opt >= num_options + BASE_OPTNUM) {
152                         char *err;
153                         err = talloc_asprintf(tmp_ctx, "%s: %s",
154                                               poptBadOption(pc, POPT_BADOPTION_NOALIAS),
155                                               poptStrerror(opt));
156                         mprSetVar(options, "ERROR", mprString(err));
157                         talloc_free(tmp_ctx);
158                         mpr_Return(eid, mprCreateUndefinedVar());
159                         return 0;
160                 }
161                 opt -= BASE_OPTNUM;
162                 arg = poptGetOptArg(pc);
163                 if (arg == NULL) {
164                         mprSetVar(options, opt_names[opt], mprCreateBoolVar(1));
165                 } else if (long_options[opt].argInfo == POPT_ARG_INT) {
166                         int v = strtol(arg, NULL, 0);
167                         mprSetVar(options, opt_names[opt], mprCreateIntegerVar(v));
168                 } else {
169                         mprSetVar(options, opt_names[opt], mprString(arg));
170                 }
171         }
172
173         /* setup options.argv list */
174         mprSetVar(options, "ARGV", mprList("ARGV", poptGetArgs(pc)));
175
176         poptFreeContext(pc);
177
178         talloc_free(tmp_ctx);
179
180         /* setup methods */
181         mprSetCFunction(options, "get_credentials", ejs_credentials_cmdline);
182
183         return 0;
184 }
185
186
187
188 /*
189   setup C functions that be called from ejs
190 */
191 void smb_setup_ejs_options(void)
192 {
193         ejsDefineCFunction(-1, "GetOptions", ejs_GetOptions, NULL, MPR_VAR_SCRIPT_HANDLE);
194 }