00001
00002
00003
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
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
00045
00046 if (string_Eq(recipient, ""))
00047 recipient = "*";
00048
00049
00050
00051
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
00121
00122
00123
00124
00125
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
00155
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
00167
00168
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
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
00269
00270
00271
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
00282 c = class[0];
00283 if (c == UNSUBSCRIBE_CHARACTER || c == PUNT_CHARACTER)
00284 class++;
00285
00286
00287 macro_sub(class);
00288 macro_sub(instance);
00289 macro_sub(recipient);
00290
00291
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
00328
00329
00330
00331
00332
00333
00334
00335
00336 if (subscriptions_file)
00337 load_subscriptions_from_file(subscriptions_file);
00338 }