[gaim-migrate @ 3006]
[pidgin-git.git] / src / aim.c
blob7bb81464f568c9d86d33ff14deb61738566bac94
1 /*
2 * gaim
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #ifdef USE_APPLET
26 #include "applet.h"
27 #include <gnome.h>
28 #else
29 #ifdef USE_GNOME
30 #include <gnome.h>
31 #endif /* USE_GNOME */
32 #endif /* USE_APPLET */
33 #ifdef GAIM_PLUGINS
34 #include <dlfcn.h>
35 #endif /* GAIM_PLUGINS */
36 #include <gtk/gtk.h>
37 #include <gdk/gdkx.h>
38 #include <gdk/gdk.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/stat.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <errno.h>
46 #include <sys/un.h>
47 #include <sys/wait.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include <stdlib.h>
52 #include <ctype.h>
53 #include "prpl.h"
54 #include "gaim.h"
55 #include "pixmaps/logo.xpm"
56 #if HAVE_SIGNAL_H
57 #include <signal.h>
58 #endif
59 #include "locale.h"
60 #include "gtkticker.h"
61 #include "gtkspell.h"
62 #ifndef USE_APPLET
63 #include <getopt.h>
64 #endif
66 static gchar *ispell_cmd[] = { "ispell", "-a", NULL };
68 static GtkWidget *name;
69 static GtkWidget *pass;
71 GList *log_conversations = NULL;
72 GList *buddy_pounces = NULL;
73 GSList *away_messages = NULL;
74 GList *conversations = NULL;
75 GSList *message_queue = NULL;
76 GSList *away_time_queue = NULL;
78 GtkWidget *mainwindow = NULL;
80 int opt_away = 0;
81 char *opt_away_arg = NULL;
82 char *opt_rcfile_arg = NULL;
83 int opt_debug = 0;
85 void BuddyTickerCreateWindow(void);
87 void cancel_logon(void)
89 #ifdef USE_APPLET
90 applet_buddy_show = FALSE;
91 if (mainwindow)
92 gtk_widget_hide(mainwindow);
93 #else
94 #ifdef GAIM_PLUGINS
95 /* first we tell those who have requested it we're quitting */
96 plugin_event(event_quit, 0, 0, 0, 0);
98 /* then we remove everyone in a mass suicide */
99 remove_all_plugins();
100 #endif /* GAIM_PLUGINS */
101 #ifdef USE_PERL
102 perl_end();
103 #endif
105 gtk_main_quit();
106 #endif /* USE_APPLET */
109 static int snd_tmout;
110 int logins_not_muted = 1;
111 static void sound_timeout()
113 logins_not_muted = 1;
114 gtk_timeout_remove(snd_tmout);
117 /* we need to do this for Oscar because serv_login only starts the login
118 * process, it doesn't end there. gaim_setup will be called later from
119 * oscar.c, after the buddy list is made and serv_finish_login is called */
120 void gaim_setup(struct gaim_connection *gc)
122 if ((sound_options & OPT_SOUND_LOGIN) && (sound_options & OPT_SOUND_SILENT_SIGNON)) {
123 logins_not_muted = 0;
124 snd_tmout = gtk_timeout_add(10000, (GtkFunction)sound_timeout, NULL);
126 #ifdef USE_APPLET
127 set_user_state(online);
128 applet_widget_register_callback(APPLET_WIDGET(applet),
129 "signoff", _("Signoff"), (AppletCallbackFunc)signoff_all, NULL);
130 #endif /* USE_APPLET */
134 static void dologin(GtkWidget *widget, GtkWidget *w)
136 struct aim_user *u;
137 const char *username = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(name)->entry));
138 const char *password = gtk_entry_get_text(GTK_ENTRY(pass));
140 if (!strlen(username)) {
141 do_error_dialog(_("Please enter your logon"), _("Signon Error"));
142 return;
145 /* if there is more than one user of the same name, then fuck
146 * them, they just have to use the account editor to sign in
147 * the second one */
149 u = find_user(username, -1);
150 if (!u)
151 u = new_user(username, DEFAULT_PROTO, OPT_USR_REM_PASS);
152 g_snprintf(u->password, sizeof u->password, "%s", password);
153 save_prefs();
154 serv_login(u);
158 static void doenter(GtkWidget *widget, GtkWidget *w)
160 if (widget == name) {
161 gtk_entry_set_text(GTK_ENTRY(pass), "");
162 gtk_entry_select_region(GTK_ENTRY(GTK_COMBO(name)->entry), 0, 0);
163 gtk_widget_grab_focus(pass);
164 } else if (widget == pass) {
165 dologin(widget, w);
170 static void combo_changed(GtkWidget *w, GtkWidget *combo)
172 const char *txt = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
173 struct aim_user *u;
175 u = find_user(txt, -1);
177 if (u && u->options & OPT_USR_REM_PASS) {
178 gtk_entry_set_text(GTK_ENTRY(pass), u->password);
179 } else {
180 gtk_entry_set_text(GTK_ENTRY(pass), "");
185 static GList *combo_user_names()
187 GSList *usr = aim_users;
188 GList *tmp = NULL;
189 struct aim_user *u;
191 if (!usr)
192 return g_list_append(NULL, "<New User>");
194 while (usr) {
195 u = (struct aim_user *)usr->data;
196 tmp = g_list_append(tmp, u->username);
197 usr = usr->next;
200 return tmp;
204 void show_login()
206 GtkWidget *options;
207 #ifdef GAIM_PLUGINS
208 GtkWidget *plugs;
209 #endif
210 #ifndef NO_MULTI
211 GtkWidget *accts;
212 #endif
213 GtkWidget *signon;
214 GtkWidget *cancel;
215 GtkWidget *reg;
216 GtkWidget *bbox;
217 GtkWidget *hbox;
218 GtkWidget *sbox;
219 GtkWidget *label;
220 GtkWidget *table;
222 GtkWidget *pmw;
223 GdkPixmap *pm;
224 GtkStyle *style;
225 GdkBitmap *mask;
227 GList *tmp;
229 if (mainwindow) {
230 gtk_widget_show(mainwindow);
231 return;
234 mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
235 gtk_window_set_wmclass(GTK_WINDOW(mainwindow), "login", "Gaim");
236 gtk_window_set_policy(GTK_WINDOW(mainwindow), FALSE, FALSE, TRUE);
237 gtk_signal_connect(GTK_OBJECT(mainwindow), "delete_event",
238 GTK_SIGNAL_FUNC(cancel_logon), mainwindow);
239 gtk_window_set_title(GTK_WINDOW(mainwindow), _("Gaim - Login"));
240 gtk_widget_realize(mainwindow);
241 aol_icon(mainwindow->window);
242 gdk_window_set_group(mainwindow->window, mainwindow->window);
244 table = gtk_table_new(8, 2, FALSE);
245 gtk_container_add(GTK_CONTAINER(mainwindow), table);
246 gtk_widget_show(table);
248 style = gtk_widget_get_style(mainwindow);
249 pm = gdk_pixmap_create_from_xpm_d(mainwindow->window, &mask,
250 &style->bg[GTK_STATE_NORMAL], (gchar **)gaim_logo_xpm);
251 pmw = gtk_pixmap_new(pm, mask);
252 gtk_table_attach(GTK_TABLE(table), pmw, 0, 2, 0, 1, 0, 0, 5, 5);
253 gtk_widget_show(pmw);
254 gdk_pixmap_unref(pm);
255 gdk_bitmap_unref(mask);
257 label = gtk_label_new(_("Screen Name: "));
258 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 0, 0, 5, 5);
259 gtk_widget_show(label);
261 name = gtk_combo_new();
262 tmp = combo_user_names();
263 gtk_combo_set_popdown_strings(GTK_COMBO(name), tmp);
264 g_list_free(tmp);
265 gtk_signal_connect(GTK_OBJECT(GTK_COMBO(name)->entry), "activate",
266 GTK_SIGNAL_FUNC(doenter), mainwindow);
267 gtk_signal_connect(GTK_OBJECT(GTK_COMBO(name)->entry), "changed",
268 GTK_SIGNAL_FUNC(combo_changed), name);
269 gtk_widget_set_usize(name, 100, 0);
270 gtk_table_attach(GTK_TABLE(table), name, 1, 2, 2, 3, 0, 0, 5, 5);
271 gtk_widget_show(name);
273 label = gtk_label_new(_("Password: "));
274 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 0, 0, 5, 5);
275 gtk_widget_show(label);
277 pass = gtk_entry_new();
278 gtk_widget_set_usize(pass, 100, 0);
279 gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE);
280 gtk_signal_connect(GTK_OBJECT(pass), "activate", GTK_SIGNAL_FUNC(doenter), mainwindow);
281 gtk_table_attach(GTK_TABLE(table), pass, 1, 2, 3, 4, 0, 0, 5, 5);
282 gtk_widget_show(pass);
284 sbox = gtk_vbox_new(TRUE, 5);
285 gtk_container_border_width(GTK_CONTAINER(sbox), 10);
286 gtk_table_attach(GTK_TABLE(table), sbox, 0, 2, 7, 8, 0, 0, 5, 5);
287 gtk_widget_show(sbox);
289 bbox = gtk_hbox_new(TRUE, 10);
290 gtk_box_pack_start(GTK_BOX(sbox), bbox, TRUE, TRUE, 0);
291 gtk_widget_show(bbox);
293 #ifndef USE_APPLET
294 cancel = gtk_button_new_with_label(_("Quit"));
295 #else
296 cancel = gtk_button_new_with_label(_("Close"));
297 #endif
298 #ifndef NO_MULTI
299 accts = gtk_button_new_with_label(_("Accounts"));
300 #endif
301 signon = gtk_button_new_with_label(_("Signon"));
303 if (misc_options & OPT_MISC_COOL_LOOK) {
304 gtk_button_set_relief(GTK_BUTTON(cancel), GTK_RELIEF_NONE);
305 #ifndef NO_MULTI
306 gtk_button_set_relief(GTK_BUTTON(accts), GTK_RELIEF_NONE);
307 #endif
308 gtk_button_set_relief(GTK_BUTTON(signon), GTK_RELIEF_NONE);
311 gtk_signal_connect(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(cancel_logon), mainwindow);
312 #ifndef NO_MULTI
313 gtk_signal_connect(GTK_OBJECT(accts), "clicked", GTK_SIGNAL_FUNC(account_editor), mainwindow);
314 #endif
315 gtk_signal_connect(GTK_OBJECT(signon), "clicked", GTK_SIGNAL_FUNC(dologin), mainwindow);
317 gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
318 #ifndef NO_MULTI
319 gtk_box_pack_start(GTK_BOX(bbox), accts, TRUE, TRUE, 0);
320 #endif
321 gtk_box_pack_start(GTK_BOX(bbox), signon, TRUE, TRUE, 0);
323 gtk_widget_show(cancel);
324 #ifndef NO_MULTI
325 gtk_widget_show(accts);
326 #endif
327 gtk_widget_show(signon);
329 hbox = gtk_hbox_new(TRUE, 10);
330 gtk_box_pack_start(GTK_BOX(sbox), hbox, TRUE, TRUE, 0);
331 gtk_widget_show(hbox);
333 reg = gtk_button_new_with_label(_("About"));
334 options = gtk_button_new_with_label(_("Options"));
335 #ifdef GAIM_PLUGINS
336 plugs = gtk_button_new_with_label(_("Plugins"));
337 #endif
338 if (misc_options & OPT_MISC_COOL_LOOK) {
339 gtk_button_set_relief(GTK_BUTTON(reg), GTK_RELIEF_NONE);
340 gtk_button_set_relief(GTK_BUTTON(options), GTK_RELIEF_NONE);
341 #ifdef GAIM_PLUGINS
342 gtk_button_set_relief(GTK_BUTTON(plugs), GTK_RELIEF_NONE);
343 #endif
346 gtk_signal_connect(GTK_OBJECT(reg), "clicked", GTK_SIGNAL_FUNC(show_about), NULL);
347 gtk_signal_connect(GTK_OBJECT(options), "clicked", GTK_SIGNAL_FUNC(show_prefs), NULL);
348 #ifdef GAIM_PLUGINS
349 gtk_signal_connect(GTK_OBJECT(plugs), "clicked", GTK_SIGNAL_FUNC(show_plugins), NULL);
350 #endif
352 gtk_box_pack_start(GTK_BOX(hbox), reg, TRUE, TRUE, 0);
353 gtk_box_pack_start(GTK_BOX(hbox), options, TRUE, TRUE, 0);
354 #ifdef GAIM_PLUGINS
355 gtk_box_pack_start(GTK_BOX(hbox), plugs, TRUE, TRUE, 0);
356 #endif
358 gtk_widget_show(reg);
359 gtk_widget_show(options);
360 #ifdef GAIM_PLUGINS
361 gtk_widget_show(plugs);
362 #endif
364 if (aim_users) {
365 struct aim_user *c = (struct aim_user *)aim_users->data;
366 if (c->options & OPT_USR_REM_PASS) {
367 combo_changed(NULL, name);
368 gtk_widget_grab_focus(signon);
369 } else {
370 gtk_widget_grab_focus(pass);
372 } else {
373 gtk_widget_grab_focus(name);
376 gtk_widget_show(mainwindow);
379 #if HAVE_SIGNAL_H
380 void sighandler(int sig)
382 switch (sig) {
383 case SIGHUP:
384 debug_printf("caught signal %d\n", sig);
385 signoff_all(NULL, NULL);
386 break;
387 case SIGSEGV:
388 core_quit();
389 #ifndef DEBUG
390 fprintf(stderr, "Gaim has segfaulted and attempted to dump a core file.\n"
391 "This is a bug in the software and has happened through\n"
392 "no fault of your own.\n\n"
393 "It is possible that this bug is already fixed in CVS.\n"
394 "You can get a tarball of CVS from the Gaim website, at\n"
395 WEBSITE "gaim-CVS.tar.gz.\n\n"
396 "If you are already using CVS, or can reproduce the crash\n"
397 "using the CVS version, please notify the gaim maintainers\n"
398 "by reporting a bug at\n"
399 WEBSITE "bug.php3\n\n"
400 "Please make sure to specify what you were doing at the time,\n"
401 "and post the backtrace from the core file. If you do not know\n"
402 "how to get the backtrace, please get instructions at\n"
403 WEBSITE "gdb.php. If you need further\n"
404 "assistance, please IM either RobFlynn or SeanEgn and\n"
405 "they can help you.\n");
406 #endif
407 abort();
408 break;
409 default:
410 debug_printf("caught signal %d\n", sig);
411 gtkspell_stop();
412 signoff_all(NULL, NULL);
413 #ifdef GAIM_PLUGINS
414 remove_all_plugins();
415 #endif
416 if (gtk_main_level())
417 gtk_main_quit();
418 core_quit();
419 exit(0);
422 #endif
424 static gboolean socket_readable(GIOChannel *source, GIOCondition cond, gpointer ud)
426 guchar type;
427 guchar subtype;
428 guint32 len;
429 guchar *data;
430 guint32 x;
432 debug_printf("Core says: ");
433 g_io_channel_read(source, &type, sizeof(type), &x);
434 if (x == 0) {
435 debug_printf("CORE IS GONE!\n");
436 g_io_channel_close(source);
437 return FALSE;
439 debug_printf("%d ", type);
440 g_io_channel_read(source, &subtype, sizeof(subtype), &x);
441 if (x == 0) {
442 debug_printf("CORE IS GONE!\n");
443 g_io_channel_close(source);
444 return FALSE;
446 debug_printf("%d ", subtype);
447 g_io_channel_read(source, (guchar *)&len, sizeof(len), &x);
448 if (x == 0) {
449 debug_printf("CORE IS GONE!\n");
450 g_io_channel_close(source);
451 return FALSE;
453 debug_printf("(%d bytes)\n", len);
455 data = g_malloc(len);
456 g_io_channel_read(source, data, len, &x);
457 if (x != len) {
458 debug_printf("CORE IS GONE! (read %d/%d bytes)\n", x, len);
459 g_free(data);
460 g_io_channel_close(source);
461 return FALSE;
464 g_free(data);
465 return TRUE;
468 static int open_socket(char *name)
470 struct sockaddr_un saddr;
471 gint fd;
473 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) {
474 saddr.sun_family = AF_UNIX;
475 g_snprintf(saddr.sun_path, 108, "%s", name);
476 if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) != -1)
477 return fd;
478 else
479 debug_printf("Failed to assign %s to a socket (Error: %s)",
480 saddr.sun_path, strerror(errno));
481 } else
482 debug_printf("Unable to open socket: %s", strerror(errno));
483 close(fd);
484 return -1;
487 static int ui_main()
489 GIOChannel *channel;
490 int UI_fd;
491 char name[256];
493 g_snprintf(name, sizeof(name), "%s/gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), getpid());
495 UI_fd = open_socket(name);
496 if (UI_fd < 0)
497 return 1;
499 channel = g_io_channel_unix_new(UI_fd);
500 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, socket_readable, NULL);
501 return 0;
504 static void set_first_user(char *name)
506 struct aim_user *u;
508 u = find_user(name, -1);
510 if (!u) { /* new user */
511 u = g_new0(struct aim_user, 1);
512 g_snprintf(u->username, sizeof(u->username), "%s", name);
513 u->protocol = DEFAULT_PROTO;
514 aim_users = g_slist_prepend(aim_users, u);
515 } else { /* user already exists */
516 aim_users = g_slist_remove(aim_users, u);
517 aim_users = g_slist_prepend(aim_users, u);
519 save_prefs();
522 /* FUCKING GET ME A TOWEL! */
523 int main(int argc, char *argv[])
525 int opt_acct = 0, opt_help = 0, opt_version = 0, opt_login = 0, do_login_ret = -1;
526 char *opt_user_arg = NULL, *opt_login_arg = NULL;
527 #ifndef USE_APPLET
528 int opt, opt_user = 0;
529 int i;
531 #ifdef USE_GNOME
532 struct poptOption popt_options[] = {
533 {"acct", 'a', POPT_ARG_NONE, &opt_acct, 'a',
534 "Display account editor window", NULL},
535 {"away", 'w', POPT_ARG_STRING, NULL, 'w',
536 "Make away on signon (optional argument MESG specifies name of away message to use)",
537 "[MESG]"},
538 {"login", 'l', POPT_ARG_STRING, NULL, 'l',
539 "Automatically login (optional argument NAME specifies account(s) to use)", "[NAME]"},
540 {"user", 'u', POPT_ARG_STRING, &opt_user_arg, 'u',
541 "Use account NAME", "NAME"},
542 {"file", 'f', POPT_ARG_STRING, &opt_rcfile_arg, 'f',
543 "Use FILE as config", "FILE"},
544 {"debug", 'd', POPT_ARG_NONE, &opt_debug, 'd',
545 "Print debugging messages to stdout", NULL},
546 {0, 0, 0, 0, 0, 0, 0}
548 #endif /* USE_GNOME */
549 struct option long_options[] = {
550 {"acct", no_argument, NULL, 'a'},
551 /*{"away", optional_argument, NULL, 'w'}, */
552 {"help", no_argument, NULL, 'h'},
553 /*{"login", optional_argument, NULL, 'l'}, */
554 {"user", required_argument, NULL, 'u'},
555 {"file", required_argument, NULL, 'f'},
556 {"debug", no_argument, NULL, 'd'},
557 {"version", no_argument, NULL, 'v'},
558 {0, 0, 0, 0}
560 #endif
562 #ifdef DEBUG
563 opt_debug = 1;
564 #endif
566 #ifdef ENABLE_NLS
567 bindtextdomain(PACKAGE, LOCALEDIR);
568 textdomain(PACKAGE);
569 #endif
571 #if HAVE_SIGNAL_H
572 /* Let's not violate any PLA's!!!! */
573 signal(SIGSEGV, sighandler);
574 signal(SIGHUP, sighandler);
575 signal(SIGINT, sighandler);
576 signal(SIGTERM, sighandler);
577 signal(SIGQUIT, sighandler);
578 signal(SIGPIPE, SIG_IGN);
579 #endif
582 #ifdef USE_APPLET
583 init_applet_mgr(argc, argv);
584 #else
585 for (i = 0; i < argc; i++) {
586 /* --login option */
587 if (strstr(argv[i], "--l") == argv[i]) {
588 char *equals;
589 opt_login = 1;
590 if ((equals = strchr(argv[i], '=')) != NULL) {
591 /* --login=NAME */
592 opt_login_arg = g_strdup(equals + 1);
593 if (strlen(opt_login_arg) == 0) {
594 g_free(opt_login_arg);
595 opt_login_arg = NULL;
597 } else if (i + 1 < argc && argv[i + 1][0] != '-') {
598 /* --login NAME */
599 opt_login_arg = g_strdup(argv[i + 1]);
600 strcpy(argv[i + 1], " ");
602 strcpy(argv[i], " ");
604 /* -l option */
605 else if (strstr(argv[i], "-l") == argv[i]) {
606 opt_login = 1;
607 if (strlen(argv[i]) > 2) {
608 /* -lNAME */
609 opt_login_arg = g_strdup(argv[i] + 2);
610 } else if (i + 1 < argc && argv[i + 1][0] != '-') {
611 /* -l NAME */
612 opt_login_arg = g_strdup(argv[i + 1]);
613 strcpy(argv[i + 1], " ");
615 strcpy(argv[i], " ");
617 /* --away option */
618 else if (strstr(argv[i], "--aw") == argv[i]) {
619 char *equals;
620 opt_away = 1;
621 if ((equals = strchr(argv[i], '=')) != NULL) {
622 /* --away=MESG */
623 opt_away_arg = g_strdup(equals + 1);
624 if (strlen(opt_away_arg) == 0) {
625 g_free(opt_away_arg);
626 opt_away_arg = NULL;
628 } else if (i + 1 < argc && argv[i + 1][0] != '-') {
629 /* --away MESG */
630 opt_away_arg = g_strdup(argv[i + 1]);
631 strcpy(argv[i + 1], " ");
633 strcpy(argv[i], " ");
635 /* -w option */
636 else if (strstr(argv[i], "-w") == argv[i]) {
637 opt_away = 1;
638 if (strlen(argv[i]) > 2) {
639 /* -wMESG */
640 opt_away_arg = g_strdup(argv[i] + 2);
641 } else if (i + 1 < argc && argv[i + 1][0] != '-') {
642 /* -w MESG */
643 opt_away_arg = g_strdup(argv[i + 1]);
644 strcpy(argv[i + 1], " ");
646 strcpy(argv[i], " ");
650 if (opt_login) {
651 printf ("--login given with arg %s\n",
652 opt_login_arg ? opt_login_arg : "NULL");
653 exit(0);
657 gtk_set_locale();
658 #ifdef USE_GNOME
659 gnome_init_with_popt_table(PACKAGE, VERSION, argc, argv, popt_options, 0, NULL);
660 #else
661 gtk_init(&argc, &argv);
662 #endif
664 /* scan command-line options */
665 #ifdef USE_GNOME
666 opterr = 0;
667 #else
668 opterr = 1;
669 #endif
670 while ((opt = getopt_long(argc, argv, "adhu:f:v", long_options, NULL)) != -1) {
671 switch (opt) {
672 case 'u': /* set user */
673 opt_user = 1;
674 opt_user_arg = g_strdup(optarg);
675 break;
676 case 'a': /* account editor */
677 opt_acct = 1;
678 break;
679 case 'd': /* debug */
680 opt_debug = 1;
681 break;
682 case 'f':
683 opt_rcfile_arg = g_strdup(optarg);
684 break;
685 case 'v': /* version */
686 opt_version = 1;
687 break;
688 case 'h': /* help */
689 opt_help = 1;
690 break;
691 #ifndef USE_GNOME
692 case '?':
693 default:
694 show_usage(1, argv[0]);
695 return 0;
696 break;
697 #endif
701 #endif /* USE_APPLET */
703 /* show help message */
704 if (opt_help) {
705 show_usage(0, argv[0]);
706 return 0;
708 /* show version window */
709 if (opt_version) {
710 gtk_init(&argc, &argv);
711 load_prefs();
712 show_about(0, (void *)2);
713 gtk_main();
714 return 0;
718 load_prefs();
720 core_main();
721 ui_main();
723 /* set the default username */
724 if (opt_user_arg != NULL) {
725 set_first_user(opt_user_arg);
726 #ifndef USE_GNOME
727 g_free(opt_user_arg);
728 opt_user_arg = NULL;
729 #endif /* USE_GNOME */
732 if (misc_options & OPT_MISC_DEBUG)
733 show_debug();
735 if (convo_options & OPT_CONVO_CHECK_SPELLING)
736 gtkspell_start(NULL, ispell_cmd);
737 #ifdef USE_PERL
738 perl_autoload();
739 #endif
740 static_proto_init();
742 /* deal with --login */
743 if (opt_login) {
744 do_login_ret = do_auto_login(opt_login_arg);
745 if (opt_login_arg != NULL) {
746 g_free(opt_login_arg);
747 opt_login_arg = NULL;
750 #ifdef USE_APPLET
751 applet_widget_register_callback(APPLET_WIDGET(applet),
752 "prefs", _("Preferences"), show_prefs, NULL);
753 applet_widget_register_callback(APPLET_WIDGET(applet),
754 "accounts",
755 _("Accounts"), (AppletCallbackFunc)account_editor, (void *)1);
756 #ifdef GAIM_PLUGINS
757 applet_widget_register_callback(APPLET_WIDGET(applet),
758 "plugins", _("Plugins"), GTK_SIGNAL_FUNC(show_plugins), NULL);
759 #endif /* GAIM_PLUGINS */
761 if (!opt_acct)
762 auto_login();
764 applet_widget_gtk_main();
765 #else
767 if (!opt_acct)
768 auto_login();
770 if (opt_acct) {
771 account_editor(NULL, NULL);
772 } else if ((do_login_ret == -1) && !connections)
773 show_login();
775 gtk_main();
777 #endif /* USE_APPLET */
779 if (convo_options & OPT_CONVO_CHECK_SPELLING)
780 gtkspell_stop();
781 core_quit();
782 /* don't need ui_quit here because ui doesn't create anything */
784 return 0;