Standardize License information
[openafs.git] / src / WINNT / afssvrmgr / cmdline.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "svrmgr.h"
16 #include "cmdline.h"
17 #include "action.h"
18 #include "creds.h"
19
20
21 /*
22  * VARIABLES __________________________________________________________________
23  *
24  */
25
26 typedef enum {
27    swCELL,
28    swSUBSET,
29    swSERVER,
30    swRESET,
31    swCONFIRM,
32    swUSER,
33    swPASSWORD,
34    swLOOKUP,
35 } SWITCH;
36
37 static struct {
38    TCHAR szSwitch[ cchRESOURCE ];
39    BOOL fGetsValue;
40    BOOL fPresent;
41    TCHAR szValue[ cchRESOURCE ];
42 } aSWITCHES[] = {
43    { TEXT("cell"),      TRUE  },
44    { TEXT("subset"),    TRUE  },
45    { TEXT("server"),    TRUE  },
46    { TEXT("reset"),     FALSE },
47    { TEXT("confirm"),   FALSE },
48    { TEXT("user"),      TRUE  },
49    { TEXT("password"),  TRUE  },
50    { TEXT("lookup"),    FALSE }
51 };
52
53 #define nSWITCHES (sizeof(aSWITCHES) / sizeof(aSWITCHES[0]))
54
55
56 /*
57  * PROTOTYPES _________________________________________________________________
58  *
59  */
60
61 #define iswhite(_ch) ( ((_ch)==TEXT(' ')) || ((_ch)==TEXT('\t')) )
62
63 void cdecl CommandLineHelp (int ids, LPTSTR pszFormat = NULL, ...);
64
65
66 /*
67  * ROUTINES ___________________________________________________________________
68  *
69  */
70
71 CMDLINEOP ParseCommandLine (LPTSTR pszCmdLine)
72 {
73    for (size_t ii = 0; ii < nSWITCHES; ++ii)
74       aSWITCHES[ ii ].fPresent = FALSE;
75
76    // Search through pszCmdLine for switches; each switch must be
77    // preceeded by "/" or "-".
78    //
79    while (pszCmdLine && *pszCmdLine)
80       {
81       while (iswhite(*pszCmdLine))
82          ++pszCmdLine;
83       if (!*pszCmdLine)
84          break;
85
86       if ( (*pszCmdLine != '-') && (*pszCmdLine != '/') )
87          {
88          CommandLineHelp (IDS_CMDLINE_SYNTAX);
89          return opCLOSEAPP;
90          }
91
92       ++pszCmdLine;
93
94       // Okay, we've found what is probably the start of a switch.
95       // See if it matches anything.
96       //
97       for (ii = 0; ii < nSWITCHES; ++ii)
98          {
99          size_t cch = lstrlen(aSWITCHES[ ii ].szSwitch);
100          if (lstrncmpi (pszCmdLine, aSWITCHES[ ii ].szSwitch, cch))
101             continue;
102
103          // If the switch wants a value, it must be followed by ":"
104          // or whitespace; if it doesn't, it must be followed by "/"
105          // or whitespace.
106          //
107          LPTSTR pszAfter = &pszCmdLine[ cch ];
108          if (iswhite (*pszAfter) || (!*pszAfter) ||
109              ((*pszAfter == TEXT(':')) && (aSWITCHES[ ii ].fGetsValue)) ||
110              ((*pszAfter == TEXT('/')) && (!aSWITCHES[ ii ].fGetsValue)) )
111             {
112             break; // found a switch!
113             }
114          }
115
116       if (ii >= nSWITCHES)
117          {
118          TCHAR szCopy[ cchRESOURCE ];
119          lstrcpy (szCopy, pszCmdLine);
120          for (LPTSTR pch = szCopy;
121               *pch && !iswhite(*pch) && !(*pch == TEXT('/')) && !(*pch == TEXT(':'));
122               ++pch)
123             ;
124          *pch = TEXT('\0');
125          CommandLineHelp (IDS_CMDLINE_UNRECOGNIZED, TEXT("%s"), szCopy);
126          return opCLOSEAPP;
127          }
128       if (aSWITCHES[ ii ].fPresent)
129          {
130          CommandLineHelp (IDS_CMDLINE_DUPLICATE, TEXT("%s"), aSWITCHES[ ii ].szSwitch);
131          return opCLOSEAPP;
132          }
133
134       // Woo hoo!  Found what appears to be a valid switch.  Parse it now.
135       //
136       aSWITCHES[ ii ].fPresent = TRUE;
137       pszCmdLine += lstrlen( aSWITCHES[ ii ].szSwitch );
138       while (iswhite (*pszCmdLine))
139          ++pszCmdLine;
140
141       if (*pszCmdLine == TEXT(':'))
142          {
143          if (!aSWITCHES[ ii ].fGetsValue)
144             {
145             CommandLineHelp (IDS_CMDLINE_UNEXPECTVALUE, TEXT("%s"), aSWITCHES[ ii ].szSwitch);
146             return opCLOSEAPP;
147             }
148          for (++pszCmdLine; iswhite (*pszCmdLine); ++pszCmdLine)
149             ;
150          }
151
152       if (aSWITCHES[ ii ].fGetsValue)
153          {
154          if ( (*pszCmdLine == TEXT('/')) || (*pszCmdLine == TEXT('\0')) )
155             {
156             CommandLineHelp (IDS_CMDLINE_MISSINGVAL, TEXT("%s"), aSWITCHES[ ii ].szSwitch);
157             return opCLOSEAPP;
158             }
159          BOOL fQuoted = FALSE;
160          for (LPTSTR pszTarget = aSWITCHES[ ii ].szValue;
161               *pszCmdLine && !(*pszCmdLine == TEXT('/') && !fQuoted)
162                           && !(iswhite(*pszCmdLine) && !fQuoted); )
163             {
164             if (*pszCmdLine == TEXT('"'))
165                {
166                ++pszCmdLine;
167                if (fQuoted)
168                   break;
169                fQuoted = TRUE;
170                continue;
171                }
172             *pszTarget++ = *pszCmdLine++;
173             }
174          *pszTarget++ = TEXT('\0');
175          }
176       }
177
178    // Was the -CONFIRM switch given?  It works with any other switch
179    // combination.
180    //
181    if (aSWITCHES[ swCONFIRM ].fPresent)
182       {
183       Action_ShowConfirmations (TRUE);
184       }
185
186    // Now test the command-line for syntactical correctness.
187    // First test: if the SUBSET switch is given, the CELL switch must
188    // be given as well.
189    //
190    if ( (aSWITCHES[ swSUBSET ].fPresent) &&
191         (!aSWITCHES[ swCELL ].fPresent) )
192       {
193       CommandLineHelp (IDS_CMDLINE_SUBSETNOTCELL);
194       return opCLOSEAPP;
195       }
196
197    // Similarly, if the SERVER switch is given, the CELL switch must
198    // be given as well.
199    //
200    if ( (aSWITCHES[ swSERVER ].fPresent) &&
201         (!aSWITCHES[ swCELL ].fPresent) )
202       {
203       CommandLineHelp (IDS_CMDLINE_SERVERNOTCELL);
204       return opCLOSEAPP;
205       }
206
207    // And if the USER or PASSWORD switch is given, the other is required.
208    //
209    if ( (aSWITCHES[ swUSER ].fPresent && !aSWITCHES[ swPASSWORD ].fPresent) ||
210         (aSWITCHES[ swPASSWORD ].fPresent && !aSWITCHES[ swUSER ].fPresent) )
211       {
212       CommandLineHelp (IDS_CMDLINE_USERPASSWORD);
213       return opCLOSEAPP;
214       }
215
216    // Implement the command-line switches.
217    //
218    if (aSWITCHES[ swRESET ].fPresent)
219       {
220       if (aSWITCHES[ swSERVER ].fPresent)
221          {
222          ErasePreferences (aSWITCHES[ swCELL ].szValue, aSWITCHES[ swSERVER ].szValue);
223          }
224       else if (aSWITCHES[ swCELL ].fPresent)
225          {
226          ErasePreferences (aSWITCHES[ swCELL ].szValue);
227          }
228       else // neither cell nor server specified--kill just the general stuff
229          {
230          EraseSettings (REGSTR_SETTINGS_BASE, REGSTR_SETTINGS_PATH, REGVAL_SETTINGS);
231          }
232
233       Message (MB_OK | MB_ICONINFORMATION, IDS_CMDLINE_RESET_TITLE, IDS_CMDLINE_RESET_DESC);
234       return opCLOSEAPP;
235       }
236
237    if (aSWITCHES[ swUSER ].fPresent)
238       {
239       LPTSTR pszCell = (aSWITCHES[ swCELL ].fPresent) ? (aSWITCHES[ swCELL ].szValue) : NULL;
240
241       ULONG status;
242       if (!AfsAppLib_SetCredentials (pszCell, aSWITCHES[ swUSER ].szValue, aSWITCHES[ swPASSWORD ].szValue, &status))
243          {
244          ImmediateErrorDialog (status, IDS_ERROR_BAD_CREDENTIALS);
245          return opCLOSEAPP;
246          }
247       }
248
249    if (aSWITCHES[ swLOOKUP ].fPresent)
250       {
251       return opLOOKUPERRORCODE;
252       }
253
254    if (aSWITCHES[ swCELL ].fPresent)
255       {
256       LPOPENCELL_PACKET lpp = New (OPENCELL_PACKET);
257       memset (lpp, 0x00, sizeof(OPENCELL_PACKET));
258
259       lstrcpy (lpp->szCell, aSWITCHES[ swCELL ].szValue);
260       lpp->fCloseAppOnFail = TRUE;
261
262       if (aSWITCHES[ swSUBSET ].fPresent)
263          {
264          lpp->sub = Subsets_LoadSubset (lpp->szCell, aSWITCHES[ swSUBSET ].szValue);
265          if (lpp->sub == NULL)
266             {
267             Delete (lpp);
268             lpp = NULL;
269
270             CommandLineHelp (IDS_CMDLINE_INVALIDSUBSET, TEXT("%s%s"), aSWITCHES[ swCELL ].szValue, aSWITCHES[ swSUBSET ].szValue);
271             return opCLOSEAPP;
272             }
273          }
274       else if (aSWITCHES[ swSERVER ].fPresent)
275          {
276          lpp->sub = New (SUBSET);
277          memset (lpp->sub, 0x0, sizeof(SUBSET));
278          FormatMultiString (&lpp->sub->pszMonitored, TRUE, TEXT("%1"), TEXT("%s"), aSWITCHES[ swSERVER ].szValue);
279          }
280
281       StartTask (taskOPENCELL, NULL, lpp);
282       return opNOCELLDIALOG;
283       }
284
285    // Okay--nothing sufficiently special took place to prevent us
286    // from running the tool normally.
287    //
288    return opNORMAL;
289 }
290
291
292 void cdecl CommandLineHelp (int ids, LPTSTR pszFormat, ...)
293 {
294    va_list   arg;
295    va_start (arg, pszFormat);
296    vMessage (MB_OK | MB_ICONHAND, IDS_CMDLINE_TITLE, ids, pszFormat, arg);
297 }
298