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

subscriptions.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /* */
00003 /* Subscriptions.c: code to deal with subscriptions & punting:       */
00004 /* */
00005 /****************************************************************************/
00006 
00007 #include <sysdep.h>
00008 #include <netdb.h>
00009 #include "new_memory.h"
00010 #include "new_string.h"
00011 #include "int_dictionary.h"
00012 #include "jwgc.h"
00013 #include "subscriptions.h"
00014 #include "error.h"
00015 #include "file.h"
00016 #include "main.h"
00017 
00018 /****************************************************************************/
00019 /* */
00020 /* Code to implement punting of notices:                   */
00021 /* */
00022 /****************************************************************************/
00023 
00024 /*
00025  *
00026  */
00027 static int_dictionary puntable_addresses_dict = 0;
00028 
00029 static void 
00030 init_puntable_dict()
00031 {
00032         puntable_addresses_dict = int_dictionary_Create(33);
00033 }
00034 
00035 static string 
00036 address_to_string(class, instance, recipient)
00037         string class;
00038         string instance;
00039         string recipient;
00040 {
00041         string result;
00042 
00043         /*
00044          * Treat a recipient of "" as "*":
00045          */
00046         if (string_Eq(recipient, ""))
00047                 recipient = "*";
00048 
00049         /*
00050          * The following is a hack for now only.  It should be replaced with
00051          * several calls to escape_code... <<<>>>
00052          */
00053         result = string_Concat(class, "\001");
00054         result = string_Concat2(result, instance);
00055         result = string_Concat2(result, "\001");
00056         result = string_Concat2(result, recipient);
00057         string_Downcase(result);
00058 
00059         return (result);
00060 }
00061 
00062 int 
00063 puntable_address_p(class, instance, recipient)
00064         string class;
00065         string instance;
00066         string recipient;
00067 {
00068         string temp;
00069 
00070         if (!puntable_addresses_dict)
00071                 init_puntable_dict();
00072 
00073         temp = address_to_string(class, instance, recipient);
00074         if (int_dictionary_Lookup(puntable_addresses_dict, temp)) {
00075                 free(temp);
00076                 return (1);
00077         }
00078 
00079         free(temp);
00080         return (0);
00081 }
00082 
00083 void 
00084 punt(class, instance, recipient)
00085         string class;
00086         string instance;
00087         string recipient;
00088 {
00089         string temp;
00090 
00091         if (!puntable_addresses_dict)
00092                 init_puntable_dict();
00093 
00094         temp = address_to_string(class, instance, recipient);
00095         (void) int_dictionary_Define(puntable_addresses_dict, temp, 0);
00096         free(temp);
00097 }
00098 
00099 void 
00100 unpunt(class, instance, recipient)
00101         string class;
00102         string instance;
00103         string recipient;
00104 {
00105         string temp;
00106         int_dictionary_binding *binding;
00107 
00108         if (!puntable_addresses_dict)
00109                 init_puntable_dict();
00110 
00111         temp = address_to_string(class, instance, recipient);
00112         binding = int_dictionary_Define(puntable_addresses_dict, temp, 0);
00113         free(temp);
00114         if (binding)
00115                 int_dictionary_Delete(puntable_addresses_dict, binding);
00116 }
00117 
00118 /****************************************************************************/
00119 /* */
00120 /* Code to implement batching [un]subscription requests:          */
00121 /* */
00122 /****************************************************************************/
00123 
00124 /*
00125  * <<<>>> these routines require jwgc_active to be false (0)
00126  */
00127 
00128 #define  BATCH_SIZE   20
00129 
00130 static int subscription_list_size = 0;
00131 static JSubscription_t subscription_list[BATCH_SIZE];
00132 
00133 static int unsubscription_list_size = 0;
00134 static JSubscription_t unsubscription_list[BATCH_SIZE];
00135 
00136 static void 
00137 free_subscription_list(list, number_of_elements)
00138         JSubscription_t *list;
00139         int number_of_elements;
00140 {
00141         int i;
00142 
00143         for (i = 0; i < number_of_elements; i++) {
00144                 free(list[i].jsub_class);
00145                 free(list[i].jsub_classinst);
00146                 free(list[i].jsub_recipient);
00147         }
00148 }
00149 
00150 static void 
00151 flush_subscriptions()
00152 {
00153         /*
00154          * TRAP(JSubscribeTo(subscription_list,subscription_list_size, 0),
00155          * "while subscribing");
00156          */
00157 
00158         free_subscription_list(subscription_list, subscription_list_size);
00159         subscription_list_size = 0;
00160 }
00161 
00162 static void 
00163 flush_unsubscriptions()
00164 {
00165         /*
00166          * if (unsubscription_list_size)
00167          * TRAP(ZUnsubscribeTo(unsubscription_list, unsubscription_list_size,
00168          * 0), "while unsubscribing");
00169          */
00170 
00171         free_subscription_list(unsubscription_list, unsubscription_list_size);
00172         unsubscription_list_size = 0;
00173 }
00174 
00175 static void 
00176 subscribe(class, instance, recipient)
00177         string class;
00178         string instance;
00179         string recipient;
00180 {
00181         subscription_list[subscription_list_size].zsub_class = string_Copy(class);
00182         subscription_list[subscription_list_size].zsub_classinst = string_Copy(instance);
00183         subscription_list[subscription_list_size].zsub_recipient = string_Copy(recipient);
00184 
00185         if (++subscription_list_size == BATCH_SIZE)
00186                 flush_subscriptions();
00187 }
00188 
00189 static void 
00190 unsubscribe(class, instance, recipient)
00191         string class;
00192         string instance;
00193         string recipient;
00194 {
00195         unsubscription_list[unsubscription_list_size].zsub_class = string_Copy(class);
00196         unsubscription_list[unsubscription_list_size].zsub_classinst
00197                 = string_Copy(instance);
00198         unsubscription_list[unsubscription_list_size].zsub_recipient
00199                 = string_Copy(recipient);
00200 
00201         if (++unsubscription_list_size == BATCH_SIZE)
00202                 flush_unsubscriptions();
00203 }
00204 
00205 /****************************************************************************/
00206 /* */
00207 /* Code to implement reading [un]subscriptions from a file:         */
00208 /* */
00209 /****************************************************************************/
00210 
00211 #define TOKEN_HOSTNAME  "%host%"
00212 #define TOKEN_CANONNAME "%canon%"
00213 #define TOKEN_ME        "%me%"
00214 #define TOKEN_WILD      "*"
00215 
00216 char ourhost[MAXHOSTNAMELEN], ourhostcanon[MAXHOSTNAMELEN];
00217 
00218 static void 
00219 inithosts()
00220 {
00221         struct hostent *hent;
00222         if (gethostname(ourhost, sizeof(ourhost) - 1) == -1) {
00223                 ERROR3("unable to retrieve hostname, %s and %s will be wrong in subscriptions.\n", TOKEN_HOSTNAME, TOKEN_CANONNAME);
00224                 return;
00225         }
00226 
00227         if (!(hent = gethostbyname(ourhost))) {
00228                 ERROR2("unable to resolve hostname, %s will be wrong in subscriptions.\n", TOKEN_CANONNAME);
00229                 return;
00230         }
00231         (void) strncpy(ourhostcanon, hent->h_name, sizeof(ourhostcanon) - 1);
00232         return;
00233 }
00234 
00235 static void 
00236 macro_sub(str)
00237         char *str;
00238 {
00239         static int initedhosts = 0;
00240 
00241         if (!initedhosts) {
00242                 inithosts();
00243                 initedhosts = 1;
00244         }
00245         if (string_Eq(str, TOKEN_ME))
00246                 strcpy(str, getlogin());
00247         else if (string_Eq(str, TOKEN_HOSTNAME))
00248                 strcpy(str, ourhost);
00249         else if (string_Eq(str, TOKEN_CANONNAME))
00250                 strcpy(str, ourhostcanon);
00251 }
00252 
00253 #define  UNSUBSCRIBE_CHARACTER  '!'
00254 #define  PUNT_CHARACTER         '-'
00255 
00256 static void 
00257 load_subscriptions_from_file(file)
00258         FILE *file;
00259 {
00260         char line[BUFSIZ];
00261         char class_buffer[BUFSIZ], instance[BUFSIZ], recipient[BUFSIZ];
00262         char *class, *temp;
00263         char c;
00264 
00265         while ((!feof(file)) && (!ferror(file))) {
00266                 if (fgets(line, BUFSIZ, file)) {
00267                         class = class_buffer;
00268                         /* Parse line */
00269                         /*
00270                          * <<<>>> The below does NOT work is the recipient
00271                          * field  is "":
00272                          */
00273                         if (temp = strchr(line, '#'))
00274                                 *temp = '\0';
00275                         for (temp = line; *temp && *temp == ' '; temp++);
00276                         if (!*temp || *temp == '\n')
00277                                 continue;
00278 
00279                         sscanf(temp, "%[^,],%[^,],%s", class, instance, recipient);
00280 
00281                         /* skip type indicator if any: */
00282                         c = class[0];
00283                         if (c == UNSUBSCRIBE_CHARACTER || c == PUNT_CHARACTER)
00284                                 class++;
00285 
00286                         /* perform macro substitutions */
00287                         macro_sub(class);
00288                         macro_sub(instance);
00289                         macro_sub(recipient);
00290 
00291                         /* do the right thing with it */
00292                         switch (c) {
00293                                 case UNSUBSCRIBE_CHARACTER:
00294                                         unsubscribe(class, instance, recipient);
00295                                         break;
00296                                 case PUNT_CHARACTER:
00297                                         punt(class, instance, recipient);
00298                                         break;
00299                                 default:
00300                                         subscribe(class, instance, recipient);
00301                                         break;
00302                         }
00303                 }
00304                 else {
00305                         break;
00306                 }
00307         }
00308 
00309         if (ferror(file)) {
00310                 fprintf(stderr, "jwgc: Error while reading from subscription file");
00311                 exit(1);
00312         }
00313 
00314         flush_subscriptions();
00315         flush_unsubscriptions();
00316 
00317         fclose(file);
00318 }
00319 
00320 #define DEFSUBS "/dev/null"
00321 
00322 static void 
00323 load_subscriptions()
00324 {
00325         FILE *subscriptions_file;
00326 
00327         /* no system default sub file on client--they live on the server */
00328         /*
00329          * BUT...we need to use something to call
00330          * load_subscriptions_from_file, so we use /dev/null
00331          */
00332         /*
00333          * subscriptions_file = locate_file(subscriptions_filename_override,
00334          * USRSUBS, DEFSUBS);
00335          */
00336         if (subscriptions_file)
00337                 load_subscriptions_from_file(subscriptions_file);
00338 }


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