Removed redundant LANGUAGE statements.
[wine] / programs / regedit / regedit.c
1 /*
2  * Windows regedit.exe registry editor implementation.
3  *
4  * Copyright 2002 Andriy Palamarchuk
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <windows.h>
24 #include "regproc.h"
25
26 static char *usage =
27 "Usage:\n"
28 "    regedit filename\n"
29 "    regedit /E filename [regpath]\n"
30 "    regedit /D regpath\n"
31 "\n"
32 "filename - registry file name\n"
33 "regpath - name of the registry key\n"
34 "\n"
35 "When is called without any switches adds contents of the specified\n"
36 "registry file to the registry\n"
37 "\n"
38 "Switches:\n"
39 "    /E - exports contents of the specified registry key to the specified\n"
40 "       file. Exports the whole registry if no key is specified.\n"
41 "    /D - deletes specified registry key\n"
42 "    /S - silent execution, can be used with any other switch.\n"
43 "       The only existing mode, exists for compatibility with Windows regedit.\n"
44 "    /V - advanced mode, can be used with any other switch.\n"
45 "       Ignored, exists for compatibility with Windows regedit.\n"
46 "    /L - location of system.dat file. Can be used with any other switch.\n"
47 "       Ignored. Exists for compatibility with Windows regedit.\n"
48 "    /R - location of user.dat file. Can be used with any other switch.\n"
49 "       Ignored. Exists for compatibility with Windows regedit.\n"
50 "    /? - print this help. Any other switches are ignored.\n"
51 "    /C - create registry from. Not implemented.\n"
52 "\n"
53 "The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
54 "This program is command-line compatible with Microsoft Windows\n"
55 "regedit. The difference with Windows regedit - this application has\n"
56 "command-line interface only.\n";
57
58 typedef enum {
59     ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
60 } REGEDIT_ACTION;
61
62 /**
63  * Process unknown switch.
64  *
65  * Params:
66  *   chu - the switch character in upper-case.
67  *   s - the command line string where s points to the switch character.
68  */
69 void error_unknown_switch(char chu, char *s)
70 {
71     if (isalpha(chu))
72     {
73         printf("%s: Undefined switch /%c!\n", getAppName(), chu);
74     } else {
75         printf("%s: Alphabetic character is expected after '%c' "
76                "in switch specification\n", getAppName(), *(s - 1));
77     }
78     exit(1);
79 }
80
81 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
82                    LPSTR lpCmdLine, int nCmdShow)
83 {
84     REGEDIT_ACTION action = ACTION_UNDEF;
85     LPSTR s = lpCmdLine;        /* command line pointer */
86     CHAR ch = *s;               /* current character */
87
88     setAppName("regedit");
89     while (ch && ((ch == '-') || (ch == '/')))
90     {
91         char chu;
92         char ch2;
93
94         s++;
95         ch = *s;
96         ch2 = *(s+1);
97         chu = toupper(ch);
98         if (!ch2 || isspace(ch2))
99         {
100             if (chu == 'S' || chu == 'V')
101             {
102                 /* ignore these switches */
103             } else {
104                 switch (chu)
105                 {
106                 case 'D':
107                     action = ACTION_DELETE;
108                     break;
109                 case 'E':
110                     action = ACTION_EXPORT;
111                     break;
112                 case '?':
113                     printf(usage);
114                     exit(0);
115                     break;
116                 default:
117                     error_unknown_switch(chu, s);
118                     break;
119                 }
120             }
121             s++;
122         } else {
123             if (ch2 == ':')
124             {
125                 switch (chu)
126                 {
127                 case 'L':
128                     /* fall through */
129                 case 'R':
130                     s += 2;
131                     while (*s && !isspace(*s))
132                     {
133                         s++;
134                     }
135                     break;
136                 default:
137                     error_unknown_switch(chu, s);
138                     break;
139                 }
140             } else {
141                 /* this is a file name, starting from '/' */
142                 s--;
143                 break;
144             }
145         }
146         /* skip spaces to the next parameter */
147         ch = *s;
148         while (ch && isspace(ch))
149         {
150             s++;
151             ch = *s;
152         }
153     }
154
155     if (action == ACTION_UNDEF)
156     {
157         action = ACTION_ADD;
158     }
159
160     switch (action)
161     {
162     case ACTION_ADD:
163     {
164         CHAR filename[MAX_PATH];
165         FILE *reg_file;
166
167         get_file_name(&s, filename);
168         if (!filename[0])
169         {
170             printf("%s: No file name is specified\n%s", getAppName(), usage);
171             exit(1);
172         }
173
174         while(filename[0])
175         {
176             reg_file = fopen(filename, "r");
177             if (reg_file)
178             {
179                 processRegLines(reg_file, doSetValue);
180             } else {
181                 perror("");
182                 printf("%s: Can't open file \"%s\"\n", getAppName(), filename);
183                 exit(1);
184             }
185             get_file_name(&s, filename);
186         }
187         break;
188     }
189     case ACTION_DELETE:
190     {
191         CHAR reg_key_name[KEY_MAX_LEN];
192
193         get_file_name(&s, reg_key_name);
194         if (!reg_key_name[0])
195         {
196             printf("%s: No registry key is specified for removal\n%s",
197                    getAppName(), usage);
198             exit(1);
199         }
200         delete_registry_key(reg_key_name);
201         break;
202     }
203     case ACTION_EXPORT:
204     {
205         CHAR filename[MAX_PATH];
206
207         filename[0] = '\0';
208         get_file_name(&s, filename);
209         if (!filename[0])
210         {
211             printf("%s: No file name is specified\n%s", getAppName(), usage);
212             exit(1);
213         }
214
215         if (s[0])
216         {
217             CHAR reg_key_name[KEY_MAX_LEN];
218
219             get_file_name(&s, reg_key_name);
220             export_registry_key(filename, reg_key_name);
221         } else {
222             export_registry_key(filename, NULL);
223         }
224         break;
225     }
226     default:
227         printf("%s: Unhandled action!\n", getAppName());
228         exit(1);
229         break;
230     }
231     return 0;
232 }