Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

main.c

Go to the documentation of this file.
00001 #include "mux.h"
00002 #include "file.h"
00003 #include "parser.h"
00004 #include "port.h"
00005 #include "main.h"
00006 
00007 #define ALARMTIMEOUT 60
00008 
00009 jabconn jab_c = NULL;
00010 jwgconn jwg_c = NULL;
00011 time_t jab_connect_time = 0;
00012 int jwgc_register = 0;
00013 int jab_reauth = 0;
00014 
00015 char *whoami = NULL;
00016 char *progname = NULL;
00017 char *description_filename_override = NULL;
00018 struct _Node *program = NULL;
00019 
00020 char *current_presence = "available";
00021 
00022 char *barebones_desc = "\
00023 fields body\n\
00024 print \"@b(Description file is broken!  This is a barebones config.)\\n\"\n\
00025 print \"Date:    \"+$date+\"\\n\"\n\
00026 print \"Time:    \"+$time+\"\\n\"\n\
00027 print \"From:    \"+$from+\"\\n\"\n\
00028 print \"Status:  \"+$status+\"\\n\"\n\
00029 print \"Show:    \"+$show+\"\\n\"\n\
00030 print \"Type:    \"+$type+\"\\n\"\n\
00031 print \"Subtype: \"+$subtype+\"\\n\"\n\
00032 print \"Body:\\n\"+$body+\"\\n\"\n\
00033 put\n\
00034 exit\n\
00035 ";
00036 
00037 void 
00038 usage()
00039 {
00040         fprintf(stderr, "\
00041 Usage: %s [-h] [-f <filename>]\n\
00042                   [-u <username>] [-p <password>]\n\
00043                   [-r <resource>] [-s <server>] [-j <jid>]\n\
00044                   [-port <port>] [-priority <priority>]\n\
00045                   [-ttymode] [-nofork] [-register]\n\
00046                   [-default <driver>] {-disable <driver>}*\n\
00047                   [output driver options]\n\
00048 ", whoami);
00049 #ifdef USE_GPGME
00050         fprintf(stderr, "\
00051                   [-gpg] [-nogpg] [-gpgpass <password>]\n\
00052 ");
00053 #endif /* USE_GPGME */
00054 #ifdef USE_SSL
00055         fprintf(stderr, "\
00056                   [-ssl] [-nossl]\n\
00057 ");
00058 #endif /* USE_SSL */
00059 #ifndef NODEBUG
00060         fprintf(stderr, "\
00061                   [-debug <flags>]\n\
00062 ");
00063 #endif /* NODEBUG */
00064         exit(1);
00065 }
00066 
00067 void 
00068 fake_startup_packet()
00069 {
00070         xode fake;
00071 
00072         fake = jabutil_msgnew("internal",
00073                         (char *)jVars_get(jVarJID),
00074                         "startup",
00075                         "Jabber Windowgram Client Started...",
00076                         NULL);
00077         jab_send(jab_c, fake);
00078         xode_free(fake);
00079 }
00080 
00081 int 
00082 read_in_description_file()
00083 {
00084         FILE *input_file;
00085         char *defdesc;
00086 
00087         defdesc = (char *)malloc(sizeof(char) * (strlen(DATADIR) + 1 +
00088                         strlen(DEFDESC) + 1));
00089 
00090         sprintf(defdesc, "%s/%s", DATADIR, DEFDESC);
00091         input_file = (FILE *) locate_file(description_filename_override,
00092                         USRDESC, defdesc);
00093         free(defdesc);
00094         if (input_file)
00095                 program = (struct _Node *) parse_file(input_file);
00096         else
00097                 program = NULL;
00098 
00099         if (program == NULL)
00100                 program = (struct _Node *) parse_buffer(barebones_desc);
00101 
00102         if (program != NULL) {
00103                 fake_startup_packet();
00104                 return 1;
00105         }
00106         else {
00107                 return 0;
00108         }
00109 }
00110 
00111 void
00112 check_live_jwgc_on_event_handler(jwgconn conn, jwgpacket packet)
00113 {
00114         fprintf(stderr, "There is already an active jwgc running!  Exiting...\n");
00115         exit(0);
00116 }
00117 
00118 void 
00119 check_live_jwgc()
00120 {
00121         jwgconn checkjwg;
00122         xode x;
00123 
00124         checkjwg = jwg_new();
00125         if (!checkjwg) {
00126                 dprintf(dExecution, "check_live_jwgc: failed to initialize jwgc connection\n");
00127                 return;
00128         }
00129 
00130         jwg_event_handler(checkjwg, check_live_jwgc_on_event_handler);
00131         jwg_start(checkjwg);
00132         if (jwg_getfd(checkjwg) < 0) {
00133                 dprintf(dExecution, "check_live_jwgc: failed to create jwgc connection\n");
00134                 return;
00135         }
00136 
00137         x = xode_new("check");
00138         jwg_send(checkjwg, x);
00139         xode_free(x);
00140 
00141         jwg_poll(checkjwg, -1);
00142         jwg_stop(checkjwg);
00143 }
00144 
00145 void 
00146 jwgc_init()
00147 {
00148         jwg_c = jwg_server();
00149         if (!jwg_c) {
00150                 fprintf(stderr, "jwgc: unable to initialize jwgc connection.\n");
00151                 exit(1);
00152         }
00153         jwg_event_handler(jwg_c, jwg_on_event_handler);
00154         jwg_servstart(jwg_c);
00155         if (jwg_getfd(jwg_c) < 0) {
00156                 fprintf(stderr, "jwgc: unable to create jwgc connection.\n");
00157                 exit(1);
00158         }
00159         mux_add_input_source(jwg_getfd(jwg_c), jwg_servrecv, jwg_c);
00160 }
00161 
00162 void 
00163 jabber_init()
00164 {
00165         jab_reauth = 0;
00166         jab_c = jab_new((char *)jVars_get(jVarJID), (char *)jVars_get(jVarPassword));
00167         if (!jab_c) {
00168                 fprintf(stderr, "jwgc: unable to create jabber connection.\n");
00169                 exit(1);
00170         }
00171         jab_c->port = *(int *)jVars_get(jVarPort);
00172         jab_packet_handler(jab_c, jab_on_packet_handler);
00173         jab_state_handler(jab_c, jab_on_state_handler);
00174         jab_start(jab_c,
00175 #ifdef USE_SSL
00176                 *(int *) jVars_get(jVarUseSSL)
00177 #else /* USE_SSL */
00178                 0
00179 #endif /* USE_SSL */
00180         );
00181         if (jwgc_register) {
00182                 dprintf(dExecution, "Registering user...\n");
00183                 jab_reg(jab_c);
00184                 jwgc_register = 0;
00185         }
00186         jab_auth(jab_c);
00187         if (jab_c->state == JABCONN_STATE_OFF) {
00188                 fprintf(stderr, "Unable to connect to jabber server.  Retrying in %d seconds.\n", ALARMTIMEOUT);
00189                 jab_reauth = 1;
00190                 return;
00191         }
00192         mux_add_input_source(jab_getfd(jab_c), jab_recv, jab_c);
00193 
00194         jab_startup(jab_c);
00195         jab_connect_time = time(0);
00196 }
00197 
00198 void 
00199 jabber_finalize()
00200 {
00201         jab_stop(jab_c);
00202         jwg_stop(jwg_c);
00203         JCleanupSocket();
00204 }
00205 
00206 void 
00207 run_initprogs()
00208 {
00209         int status;
00210         char *progname = (char *)jVars_get(jVarInitProgs);
00211 
00212         if (!progname)
00213                 return;
00214 
00215         dprintf(dExecution, "Running init program... %s\n", progname);
00216 
00217         status = system(progname);
00218         if (status == 127) {
00219                 perror("jwgc initprog exec");
00220                 fprintf(stderr, "jwgc initprog of <%s> failed: no shell.\n",
00221                         progname);
00222         }
00223         else if (status != -1 && status >> 8) {
00224                 perror("jwgc initprog exec");
00225                 fprintf(stderr, "jwgc initprog of <%s> failed with status [%d].\n",
00226                         progname, status >> 8);
00227         }
00228 }
00229 
00230 static RETSIGTYPE 
00231 signal_exit()
00232 {
00233         mux_end_loop_p = 1;
00234 }
00235 
00236 static RETSIGTYPE 
00237 signal_pipe()
00238 {
00239         fprintf(stderr, "Lost connection to server.  Retrying in %d seconds...\n", ALARMTIMEOUT);
00240         mux_delete_input_source(jab_getfd(jab_c));
00241         jab_delete(jab_c);
00242         jab_reauth = 1;
00243 }
00244 
00245 static RETSIGTYPE 
00246 signal_check()
00247 {
00248         /* char *rawstr; */
00249         xode x, y, z;
00250 
00251         dprintf(dExecution, "Checking jabber connection...\n");
00252         if (jab_reauth) {
00253                 if (jab_c) { jab_delete(jab_c); }
00254                 jabber_init();
00255         }
00256         else if (jab_c->state == JABCONN_STATE_ON) {
00257                 /*
00258                  * we're going to check server up or down by setting a
00259                  * keepalive 'pref' of sorts.  Lame, but it's the best i can
00260                  * come up with for now.
00261                  */
00262                 /*
00263                 x = jabutil_iqnew(JABPACKET__SET, NS_PRIVATE);
00264                 y = xode_get_tag(x, "query");
00265                 z = xode_insert_tag(y, "jwgc");
00266                 xode_put_attrib(z, "xmlns", "jwgc:status");
00267                 xode_put_attrib(z, "keepalive", "1");
00268                 jab_send(jab_c, x);
00269                 xode_free(x);
00270                 */
00271                 /* This should do it, and more efficiently than above. */
00272                 jab_send_raw(jab_c, " ");
00273                 if (errno == EPIPE) {
00274                         fprintf(stderr, "Lost connection to server.  Retrying in %d seconds...\n", ALARMTIMEOUT);
00275                         mux_delete_input_source(jab_getfd(jab_c));
00276                         jab_delete(jab_c);
00277                         jab_reauth = 1;
00278                 }
00279         }
00280 
00281         alarm(ALARMTIMEOUT);
00282 }
00283 
00284 /*
00285  * clean up ALL the waiting children, in case we get hit with multiple
00286  * SIGCHLD's at once, and don't process in time.
00287  */
00288 static RETSIGTYPE 
00289 signal_child()
00290 {
00291 #ifdef HAVE_WAITPID
00292         int status;
00293 #else
00294         union wait status;
00295 #endif
00296         extern int errno;
00297         int pid, old_errno = errno;
00298 
00299         do {
00300 #ifdef HAVE_WAITPID
00301                 pid = waitpid(-1, &status, WNOHANG);
00302 #else
00303                 pid = wait3(&status, WNOHANG, (struct rusage *) 0);
00304 #endif
00305         } while (pid != 0 && pid != -1);
00306         errno = old_errno;
00307 }
00308 
00309 static void 
00310 setup_signals(dofork)
00311         int dofork;
00312 {
00313 #ifdef _POSIX_VERSION
00314         struct sigaction sa;
00315 
00316         sigemptyset(&sa.sa_mask);
00317         sa.sa_flags = 0;
00318 
00319         if (dofork) {
00320                 sa.sa_handler = SIG_IGN;
00321                 sigaction(SIGINT, &sa, (struct sigaction *) 0);
00322                 sigaction(SIGTSTP, &sa, (struct sigaction *) 0);
00323                 sigaction(SIGQUIT, &sa, (struct sigaction *) 0);
00324                 sigaction(SIGTTOU, &sa, (struct sigaction *) 0);
00325         }
00326         else {
00327                 /*
00328                  * clean up on SIGINT; exiting on logout is the user's
00329                  * problem, now.
00330                  */
00331                 sa.sa_handler = signal_exit;
00332                 sigaction(SIGINT, &sa, (struct sigaction *) 0);
00333         }
00334 
00335         /* behavior never changes */
00336         sa.sa_handler = signal_exit;
00337         sigaction(SIGTERM, &sa, (struct sigaction *) 0);
00338         sigaction(SIGHUP, &sa, (struct sigaction *) 0);
00339 
00340         sa.sa_handler = SIG_IGN;
00341         sigaction(SIGPIPE, &sa, (struct sigaction *)0);
00342         /*
00343         sa.sa_handler = signal_pipe;
00344         sigaction(SIGPIPE, &sa, (struct sigaction *) 0);
00345         */
00346 
00347         sa.sa_handler = signal_child;
00348         sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
00349 
00350         sa.sa_handler = signal_check;
00351         sigaction(SIGALRM, &sa, (struct sigaction *) 0);
00352 
00353 #ifdef _AIX
00354         sa.sa_flags = SA_FULLDUMP;
00355         sa.sa_handler = SIG_DFL;
00356         sigaction(SIGSEGV, &sa, (struct sigaction *) 0);
00357 #endif
00358 
00359 #else                           /* !POSIX */
00360         if (dofork) {
00361                 /*
00362                  * Ignore keyboard signals if forking.  Bad things will
00363                  * happen.
00364                  */
00365                 signal(SIGINT, SIG_IGN);
00366                 signal(SIGTSTP, SIG_IGN);
00367                 signal(SIGTTOU, SIG_IGN);
00368                 signal(SIGQUIT, SIG_IGN);
00369         }
00370         else {
00371                 /*
00372                  * clean up on SIGINT; exiting on logout is the user's
00373                  * problem, now.
00374                  */
00375                 signal(SIGINT, signal_exit);
00376         }
00377 
00378         /* behavior never changes */
00379         signal(SIGTERM, signal_exit);
00380         signal(SIGHUP, signal_exit);
00381         signal(SIGCHLD, signal_child);
00382         signal(SIGPIPE, SIG_IGN);
00383         /* signal(SIGPIPE, signal_pipe); */
00384         signal(SIGALRM, signal_check);
00385 #endif
00386 }
00387 
00388 static void 
00389 detach()
00390 {
00391         /* detach from terminal and fork. */
00392         register int i;
00393 
00394         /* to try to get SIGHUP on user logout */
00395 #if defined(_POSIX_VERSION) && !defined(ultrix)
00396         (void) setpgid(0, tcgetpgrp(1));
00397 #else
00398         (void) setpgrp(0, getpgrp(getppid()));
00399 #endif
00400 
00401         /* fork off and let parent exit... */
00402         if ((i = fork())) {
00403                 if (i < 0) {
00404                         perror("jwgc: cannot fork, aborting:");
00405                         exit(1);
00406                 }
00407                 exit(0);
00408         }
00409 }
00410 
00411 int 
00412 main(argc, argv)
00413         int argc;
00414         char **argv;
00415 {
00416         extern char *optarg;
00417         extern int optind;
00418         char prompt[256];
00419         char **new;
00420         register char **current;
00421         int dofork = 1;
00422         int portset = 0;
00423 
00424         whoami = argv[0];
00425         progname = argv[0];
00426 #ifndef NODEBUG
00427         dinit();
00428         for (new = current = argv + 1; *current; current++) {
00429                 if (string_Eq(*current, "-debug")) {
00430                         argc -= 2;
00431                         current++;
00432                         if (!*current)
00433                                 dprinttypes();
00434                         dparseflags(*current);
00435                 }
00436         }
00437 #endif /* NODEBUG */
00438         jVars_set_defaults_handler(jwg_set_defaults_handler);
00439         jVars_init();
00440 
00441         for (new = current = argv + 1; *current; current++) {
00442                 if (string_Eq(*current, "-h") ||
00443                     string_Eq(*current, "-help")) {
00444                         usage();
00445                 }
00446 #ifndef NODEBUG
00447                 else if (string_Eq(*current, "-debug")) {
00448                         argc -= 2;
00449                         current++;
00450                         /* we already checked this above */
00451                 }
00452 #endif /* NODEBUG */
00453                 else if (string_Eq(*current, "-f") ||
00454                          string_Eq(*current, "-descfile")) {
00455                         argc -= 2;
00456                         current++;
00457                         if (!*current)
00458                                 usage();
00459                         description_filename_override = *current;
00460                 }
00461                 else if (string_Eq(*current, "-j") ||
00462                          string_Eq(*current, "-jid")) {
00463                         argc -= 2;
00464                         current++;
00465                         if (!*current)
00466                                 usage();
00467                         jVars_set(jVarJID, *current);
00468                 }
00469                 else if (string_Eq(*current, "-port")) {
00470                         argc -= 2;
00471                         current++;
00472                         if (!*current)
00473                                 usage();
00474                         jVars_set(jVarPort, *current);
00475                         portset = 1;
00476                 }
00477                 else if (string_Eq(*current, "-priority")) {
00478                         argc -= 2;
00479                         current++;
00480                         if (!*current)
00481                                 usage();
00482                         jVars_set(jVarPriority, *current);
00483                 }
00484                 else if (string_Eq(*current, "-nofork")) {
00485                         argc--;
00486                         dofork = 0;
00487                 }
00488                 else if (string_Eq(*current, "-register")) {
00489                         argc--;
00490                         jwgc_register = 1;
00491                 }
00492 #ifdef USE_SSL
00493                 else if (string_Eq(*current, "-ssl")) {
00494                         argc--;
00495                         jVars_set(jVarUseSSL, "1");
00496                 }
00497                 else if (string_Eq(*current, "-nossl")) {
00498                         argc--;
00499                         jVars_set(jVarUseSSL, "0");
00500                 }
00501 #endif /* USE_SSL */
00502 #ifdef USE_GPGME
00503                 else if (string_Eq(*current, "-gpg")) {
00504                         argc--;
00505                         jVars_set(jVarUseGPG, "1");
00506                 }
00507                 else if (string_Eq(*current, "-nogpg")) {
00508                         argc--;
00509                         jVars_set(jVarUseGPG, "0");
00510                 }
00511                 else if (string_Eq(*current, "-gpgpass")) {
00512                         argc -= 2;
00513                         current++;
00514                         if (!*current)
00515                                 usage();
00516                         jVars_set(jVarGPGPass, *current);
00517                 }
00518 #endif /* USE_GPGME */
00519                 else if (string_Eq(*current, "-u") ||
00520                          string_Eq(*current, "-username")) {
00521                         argc -= 2;
00522                         current++;
00523                         if (!*current)
00524                                 usage();
00525                         jVars_set(jVarUsername, *current);
00526                 }
00527                 else if (string_Eq(*current, "-s") ||
00528                          string_Eq(*current, "-server")) {
00529                         argc -= 2;
00530                         current++;
00531                         if (!*current)
00532                                 usage();
00533                         jVars_set(jVarServer, *current);
00534                 }
00535                 else if (string_Eq(*current, "-r") ||
00536                          string_Eq(*current, "-resource")) {
00537                         argc -= 2;
00538                         current++;
00539                         if (!*current)
00540                                 usage();
00541                         jVars_set(jVarResource, *current);
00542                 }
00543                 else if (string_Eq(*current, "-p") ||
00544                          string_Eq(*current, "-password")) {
00545                         argc -= 2;
00546                         current++;
00547                         if (!*current)
00548                                 usage();
00549                         jVars_set(jVarPassword, *current);
00550                 }
00551                 else
00552                         *(new)++ = *current;
00553         }
00554         *new = *current;
00555 
00556 #ifdef USE_SSL
00557         if (!portset && *(int *)jVars_get(jVarUseSSL)) {
00558                 jVars_set(jVarPort, DEFSSLPORT);
00559         }
00560 #endif /* USE_SSL */
00561 
00562         if (jVars_get(jVarUsername) == NULL) {
00563                 if (!jVars_set(jVarUsername, getlogin())) {
00564                         printf("No username specified.\n");
00565                         exit(0);
00566                 }
00567         }
00568 
00569         if (jVars_get(jVarPassword) == NULL) {
00570                 snprintf(prompt, 255, "Password for %s@%s:",
00571                                 (char *)jVars_get(jVarUsername),
00572                                 (char *)jVars_get(jVarServer));
00573 #ifdef HAVE_GETPASSPHRASE
00574                 if (!jVars_set(jVarPassword, getpassphrase(prompt))) {
00575 #else
00576                 if (!jVars_set(jVarPassword, getpass(prompt))) {
00577 #endif
00578                         printf("No password specified.\n");
00579                         exit(0);
00580                 }
00581         }
00582 
00583         mux_init();
00584         var_clear_all_variables();
00585         init_ports();
00586         dprintf(dExecution, "Initializing standard ports...\n");
00587         init_standard_ports(&argc, argv);
00588         if (argc > 1)
00589                 usage();
00590         check_live_jwgc();
00591         setup_signals(dofork);
00592 
00593         if (!jVars_get(jVarJID)) {
00594                 char *jwgcjid;
00595                 dprintf(dExecution, "Creating JID...\n");
00596                 jwgcjid = (char *) malloc(sizeof(char) *
00597                         (strlen((char *)jVars_get(jVarUsername))
00598                         + strlen((char *)jVars_get(jVarServer))
00599                         + strlen((char *)jVars_get(jVarResource)) + 3));
00600                 sprintf(jwgcjid, "%s@%s/%s",
00601                         (char *)jVars_get(jVarUsername),
00602                         (char *)jVars_get(jVarServer),
00603                         (char *)jVars_get(jVarResource));
00604                 dprintf(dExecution, "JID = %s\n", jwgcjid ? jwgcjid : "n/a");
00605                 jVars_set(jVarJID, jwgcjid);
00606                 free(jwgcjid);
00607         }
00608         else {
00609                 dprintf(dExecution, "JID already set to %s.\n",
00610                                 (char *)jVars_get(jVarJID));
00611         }
00612         jwgc_init();
00613         jabber_init();
00614 
00615         if (dofork)
00616                 detach();
00617 
00618         run_initprogs();
00619 
00620         read_in_description_file();
00621 
00622         alarm(ALARMTIMEOUT);
00623 
00624         mux_loop();
00625 
00626         jabber_finalize();
00627 
00628         exit(0);
00629 }


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye