Splitted SILC core library. Core library includes now only
[silc.git] / apps / silc / silc.c
1 /*
2
3   silc.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * $Id$
22  * $Log$
23  * Revision 1.4  2000/07/14 06:11:32  priikone
24  *      Fixed key-pair generation.
25  *
26  * Revision 1.3  2000/07/05 06:11:00  priikone
27  *      Added ~./silc directory checking, autoloading of keys and
28  *      tweaked the key pair generation function.
29  *
30  * Revision 1.2  2000/06/30 10:49:48  priikone
31  *      Added SOCKS4 and SOCKS5 support for SILC client.
32  *
33  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
34  *      Imported from internal CVS/Added Log headers.
35  *
36  *
37  */
38
39 #include "clientincludes.h"
40 #include "version.h"
41
42 /* Long command line options */
43 static struct option long_opts[] = 
44 {
45   /* Generic options */
46   { "server", 1, NULL, 's' },
47   { "port", 1, NULL, 'p' },
48   { "nickname", 1, NULL, 'n' },
49   { "channel", 1, NULL, 'c' },
50   { "cipher", 1, NULL, 'r' },
51   { "public-key", 1, NULL, 'b' },
52   { "private-key", 1, NULL, 'k' },
53   { "config-file", 1, NULL, 'f' },
54   { "no-silcrc", 0, NULL, 'q' },
55   { "help", 0, NULL, 'h' },
56   { "version", 0, NULL, 'V' },
57   { "list-ciphers", 0, NULL, 1 },
58   { "list-hash-funcs", 0, NULL, 2 },
59   { "list-pkcs", 0, NULL, 3 },
60
61   /* Key management options */
62   { "create-key-pair", 0, NULL, 'C' },
63   { "pkcs", 1, NULL, 10 },
64   { "bits", 1, NULL, 11 },
65
66   { NULL, 0, NULL, 0 }
67 };
68
69 /* Command line option variables */
70 static char *opt_server = NULL;
71 static int opt_port = 0;
72 static char *opt_nickname = NULL;
73 static char *opt_channel = NULL;
74 static char *opt_cipher = NULL;
75 static char *opt_public_key = NULL;
76 static char *opt_private_key = NULL;
77 static char *opt_config_file = NULL;
78 static int opt_no_silcrc = FALSE;
79
80 static int opt_create_keypair = FALSE;
81 static char *opt_pkcs = NULL;
82 static int opt_bits = 0;
83
84 /* Prints out the usage of silc client */
85
86 void usage()
87 {
88   printf("\
89 Usage: silc [options]\n\
90 \n\
91   Generic Options:\n\
92   -s, --server=HOST            Open connection to server HOST\n\
93   -p, --port=PORT              Set PORT as default port to connect\n\
94   -n, --nickname=STRING        Set default nickname on startup\n\
95   -c, --channel=STRING         Join channel on startup\n\
96   -r, --cipher=CIPHER          Use CIPHER as default cipher in SILC\n\
97   -b, --public-key=FILE        Public key used in SILC\n\
98   -k, --private-key=FILE       Private key used in SILC\n\
99   -f, --config-file=FILE       Alternate configuration file\n\
100   -q, --no-silcrc              Don't load ~/.silcrc on startup\n\
101   -h, --help                   Display this help message\n\
102   -V, --version                Display version\n\
103       --list-ciphers           List supported ciphers\n\
104       --list-hash-funcs        List supported hash functions\n\
105       --list-pkcs              List supported PKCS's\n\
106 \n\
107   Key Management Options:\n\
108   -C, --create-key-pair        Create new public key pair\n\
109       --pkcs=PKCS              Set the PKCS of the public key pair\n\
110       --bits=VALUE             Set length of the public key pair\n\
111 \n");
112 }
113
114 int main(int argc, char **argv)
115 {
116   int opt, option_index = 1;
117   int ret;
118   SilcClient silc = NULL;
119   SilcClientConfig config = NULL;
120   
121   if (argc > 1) 
122     {
123       while ((opt = 
124               getopt_long(argc, argv,
125                           "s:p:n:c:b:k:f:qhVC",
126                           long_opts, &option_index)) != EOF)
127         {
128           switch(opt) 
129             {
130               /* 
131                * Generic options
132                */
133             case 's':
134               if (optarg)
135                 opt_server = strdup(optarg);
136               break;
137             case 'p':
138               if (optarg)
139                 opt_port = atoi(optarg);
140               break;
141             case 'n':
142               if (optarg)
143                 opt_nickname = strdup(optarg);
144               break;
145             case 'c':
146               if (optarg)
147                 opt_channel = strdup(optarg);
148               break;
149             case 'r':
150               if (optarg)
151                 opt_cipher = strdup(optarg);
152               break;
153             case 'b':
154               if (optarg)
155                 opt_public_key = strdup(optarg);
156               break;
157             case 'k':
158               if (optarg)
159                 opt_private_key = strdup(optarg);
160               break;
161             case 'f':
162               if (optarg)
163                 opt_config_file = strdup(optarg);
164               break;
165             case 'q':
166               opt_no_silcrc = TRUE;
167               break;
168             case 'h':
169               usage();
170               exit(0);
171               break;
172             case 'V':
173               printf("\
174 SILC Secure Internet Live Conferencing, version %s\n", 
175                      silc_version);
176               printf("\
177 (c) 1997 - 2000 Pekka Riikonen <priikone@poseidon.pspt.fi>\n");
178               exit(0);
179               break;
180             case 1:
181               silc_client_list_ciphers();
182               exit(0);
183               break;
184             case 2:
185               silc_client_list_hash_funcs();
186               exit(0);
187               break;
188             case 3:
189               silc_client_list_pkcs();
190               exit(0);
191               break;
192
193               /*
194                * Key management options
195                */
196             case 'C':
197               opt_create_keypair = TRUE;
198               break;
199             case 10:
200               if (optarg)
201                 opt_pkcs = strdup(optarg);
202               break;
203             case 11:
204               if (optarg)
205                 opt_bits = atoi(optarg);
206               break;
207
208             default:
209               exit(0);
210               break;
211             }
212         }
213     }
214
215   /* Init signals */
216   signal(SIGHUP, SIG_DFL);
217   signal(SIGTERM, SIG_DFL);
218   signal(SIGPIPE, SIG_IGN);
219   signal(SIGCHLD, SIG_DFL);
220   signal(SIGALRM, SIG_IGN);
221   signal(SIGQUIT, SIG_IGN);
222   signal(SIGSEGV, SIG_DFL);
223   signal(SIGBUS, SIG_DFL);
224   signal(SIGFPE, SIG_DFL);
225   //  signal(SIGINT, SIG_IGN);
226   
227   if (opt_create_keypair == TRUE) {
228     /* Create new key pair and exit */
229     silc_client_create_key_pair(opt_pkcs, opt_bits, 
230                                 NULL, NULL, NULL, NULL, NULL);
231     exit(0);
232   }
233
234   /* Default configuration file */
235   if (!opt_config_file)
236     opt_config_file = strdup(SILC_CLIENT_CONFIG_FILE);
237
238   /* Read global configuration file. */
239   config = silc_client_config_alloc(opt_config_file);
240   if (config == NULL)
241     goto fail;
242
243   /* Read local configuration file */
244
245   /* Check ~/.silc directory and public and private keys */
246   if (silc_client_check_silc_dir() == FALSE)
247     goto fail;
248
249 #ifdef SOCKS
250   /* Init SOCKS */
251   SOCKSinit(argv[0]);
252 #endif
253
254   /* Allocate new client */
255   ret = silc_client_alloc(&silc);
256   if (ret == FALSE)
257     goto fail;
258
259   /* Initialize the client */
260   silc->config = config;
261   ret = silc_client_init(silc);
262   if (ret == FALSE)
263     goto fail;
264
265   /* Run the client */
266   silc_client_run(silc);
267
268   /* Stop the client. This probably has been done already but it
269      doesn't hurt to do it here again. */
270   silc_client_stop(silc);
271   silc_client_free(silc);
272   
273   exit(0);
274
275  fail:
276   if (opt_config_file)
277     silc_free(opt_config_file);
278   if (config)
279     silc_client_config_free(config);
280   if (silc)
281     silc_client_free(silc);
282   exit(1);
283 }