comparison plugins/zephyr/zephyr.c @ 1719:5800449e7ecc

[gaim-migrate @ 1729] patch by Neil Sanchala (nsanch). zlocating and signatures, as well as zephyr_normalize for all of its goodness. this is cool, zephyr might actually be useful now. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sun, 15 Apr 2001 22:48:11 +0000
parents 1e0fa7e130d0
children 004725b3a851
comparison
equal deleted inserted replaced
1718:20f070721b9f 1719:5800449e7ecc
61 /* this is so bad, and if Zephyr weren't so fucked up to begin with I 61 /* this is so bad, and if Zephyr weren't so fucked up to begin with I
62 * wouldn't do this. but it is so i will. */ 62 * wouldn't do this. but it is so i will. */
63 static guint32 nottimer = 0; 63 static guint32 nottimer = 0;
64 static guint32 loctimer = 0; 64 static guint32 loctimer = 0;
65 struct gaim_connection *zgc = NULL; 65 struct gaim_connection *zgc = NULL;
66 static GList *pending_zloc_names = NULL;
66 67
67 /* just for debugging 68 /* just for debugging
68 static void handle_unknown(ZNotice_t notice) 69 static void handle_unknown(ZNotice_t notice)
69 { 70 {
70 g_print("z_packet: %s\n", notice.z_packet); 71 g_print("z_packet: %s\n", notice.z_packet);
79 g_print("z_message_len: %d\n", notice.z_message_len); 80 g_print("z_message_len: %d\n", notice.z_message_len);
80 g_print("\n"); 81 g_print("\n");
81 } 82 }
82 */ 83 */
83 84
85 static char *zephyr_normalize(const char *orig)
86 {
87 static char buf[80];
88 if (strchr(orig, '@')) {
89 g_snprintf(buf, 80, "%s", orig);
90 } else {
91 g_snprintf(buf, 80, "%s@%s", orig, ZGetRealm());
92 }
93 return buf;
94 }
95
96 static gboolean pending_zloc(char *who)
97 {
98 GList *curr;
99 for (curr = pending_zloc_names; curr != NULL; curr = curr->next) {
100 if (!g_strcasecmp(who, (char*)curr->data)) {
101 g_free((char*)curr->data);
102 pending_zloc_names = g_list_remove(pending_zloc_names, curr->data);
103 return TRUE;
104 }
105 }
106 return FALSE;
107 }
108
109 static void zephyr_zloc(struct gaim_connection *gc, char *who)
110 {
111 ZAsyncLocateData_t ald;
112
113 if (ZRequestLocations(zephyr_normalize(who), &ald, UNACKED, ZAUTH)
114 != ZERR_NONE) {
115 return;
116 }
117 pending_zloc_names = g_list_append(pending_zloc_names,
118 g_strdup(zephyr_normalize(who)));
119 }
120
121 static void info_callback(GtkObject *obj, char *who)
122 {
123 zephyr_zloc(gtk_object_get_user_data(obj), who);
124 }
125
126 static void zephyr_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who)
127 {
128 GtkWidget *button;
129
130 button = gtk_menu_item_new_with_label(_("ZLocate"));
131 gtk_signal_connect(GTK_OBJECT(button), "activate",
132 GTK_SIGNAL_FUNC(info_callback), who);
133 gtk_object_set_user_data(GTK_OBJECT(button), gc);
134 gtk_menu_append(GTK_MENU(menu), button);
135 gtk_widget_show(button);
136 }
137
84 static void handle_message(ZNotice_t notice, struct sockaddr_in from) 138 static void handle_message(ZNotice_t notice, struct sockaddr_in from)
85 { 139 {
86 if (!g_strcasecmp(notice.z_class, LOGIN_CLASS)) { 140 if (!g_strcasecmp(notice.z_class, LOGIN_CLASS)) {
87 /* well, we'll be updating in 2 seconds anyway, might as well ignore this. */ 141 /* well, we'll be updating in 2 seconds anyway, might as well ignore this. */
88 } else if (!g_strcasecmp(notice.z_class, LOCATE_CLASS)) { 142 } else if (!g_strcasecmp(notice.z_class, LOCATE_CLASS)) {
100 } 154 }
101 if (!b) { 155 if (!b) {
102 free(user); 156 free(user);
103 return; 157 return;
104 } 158 }
159 if (pending_zloc(b->name)) {
160 ZLocations_t locs;
161 int one = 1;
162 GString *str = g_string_new("");
163 g_string_sprintfa(str, "<b>User:</b> %s<br>"
164 "<b>Alias:</b> %s<br>",
165 b->name, b->show);
166 if (!nlocs) {
167 g_string_sprintfa(str, "<br>Hidden or not logged-in");
168 }
169 for (; nlocs > 0; nlocs--) {
170 ZGetLocations(&locs, &one);
171 g_string_sprintfa(str, "<br>At %s since %s", locs.host,
172 locs.time);
173 }
174 g_show_info_text(str->str);
175 g_string_free(str, TRUE);
176 }
105 serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0, 0); 177 serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0, 0);
106 178
107 free(user); 179 free(user);
108 } 180 }
109 } else if (!g_strcasecmp(notice.z_class, "MESSAGE")) { 181 } else if (!g_strcasecmp(notice.z_class, "MESSAGE")) {
159 struct group *g = gr->data; 231 struct group *g = gr->data;
160 m = g->members; 232 m = g->members;
161 while (m) { 233 while (m) {
162 struct buddy *b = m->data; 234 struct buddy *b = m->data;
163 char *chk; 235 char *chk;
164 if (!strchr(b->name, '@')) 236 chk = g_strdup(zephyr_normalize(b->name));
165 chk = g_strdup_printf("%s@%s", b->name, ZGetRealm());
166 else
167 chk = g_strdup(b->name);
168 /* doesn't matter if this fails or not; we'll just move on to the next one */ 237 /* doesn't matter if this fails or not; we'll just move on to the next one */
169 ZRequestLocations(chk, &ald, UNACKED, ZAUTH); 238 ZRequestLocations(chk, &ald, UNACKED, ZAUTH);
170 g_free(chk); 239 g_free(chk);
171 m = m->next; 240 m = m->next;
172 } 241 }
202 *tmp = '\0'; 271 *tmp = '\0';
203 g_strchug(str); 272 g_strchug(str);
204 g_strchomp(str); 273 g_strchomp(str);
205 } 274 }
206 275
276 static void process_zsubs()
277 {
278 FILE *f;
279 gchar *fname;
280 gchar buff[BUFSIZ];
281
282 fname = g_strdup_printf("%s/.zephyr.subs", g_getenv("HOME"));
283 f = fopen(fname, "r");
284 if (f) {
285 char **triple;
286 ZSubscription_t sub;
287 char *recip;
288 while (fgets(buff, BUFSIZ, f)) {
289 strip_comments(buff);
290 if (buff[0]) {
291 triple = g_strsplit(buff, ",", 3);
292 if (triple[0] && triple[1] && triple[2]) {
293 sub.zsub_class = triple[0];
294 sub.zsub_classinst = triple[1];
295 if (!g_strcasecmp(triple[2], "%me%")) {
296 recip = g_strdup_printf("%s@%s", g_getenv("USER"),
297 ZGetRealm());
298 } else if (!g_strcasecmp(triple[2], "*")) {
299 /* wildcard */
300 recip = g_strdup_printf("@%s", ZGetRealm());
301 } else {
302 recip = g_strdup(triple[2]);
303 }
304 sub.zsub_recipient = recip;
305 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) {
306 debug_printf("Zephyr: Couldn't subscribe to %s, %s, "
307 "%s\n",
308 sub.zsub_class,
309 sub.zsub_classinst,
310 sub.zsub_recipient);
311 }
312 g_free(recip);
313 }
314 g_strfreev(triple);
315 }
316 }
317 }
318 }
319
207 static void process_anyone() 320 static void process_anyone()
208 { 321 {
209 FILE *fd; 322 FILE *fd;
210 gchar buff[BUFSIZ], *filename; 323 gchar buff[BUFSIZ], *filename;
211 324
239 sub.zsub_class = "MESSAGE"; 352 sub.zsub_class = "MESSAGE";
240 sub.zsub_classinst = "PERSONAL"; 353 sub.zsub_classinst = "PERSONAL";
241 sub.zsub_recipient = ZGetSender(); 354 sub.zsub_recipient = ZGetSender();
242 355
243 /* we don't care if this fails. i'm lying right now. */ 356 /* we don't care if this fails. i'm lying right now. */
244 ZSubscribeTo(&sub, 1, 0); 357 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) {
358 debug_printf("Zephyr: Couldn't subscribe to messages!\n");
359 }
245 360
246 account_online(zgc); 361 account_online(zgc);
247 serv_finish_login(zgc); 362 serv_finish_login(zgc);
248 363
249 if (bud_list_cache_exists(zgc)) 364 if (bud_list_cache_exists(zgc))
250 do_import(NULL, zgc); 365 do_import(NULL, zgc);
251 process_anyone(); 366 process_anyone();
252 /* should also process .zephyr.subs */ 367 /* call process_zsubs to subscribe. still commented out since I don't know
368 * how you want to handle incoming msgs from subs.
369 process_zsubs(); */
253 370
254 nottimer = gtk_timeout_add(100, check_notify, NULL); 371 nottimer = gtk_timeout_add(100, check_notify, NULL);
255 loctimer = gtk_timeout_add(2000, check_loc, NULL); 372 loctimer = gtk_timeout_add(2000, check_loc, NULL);
256 } 373 }
257 374
258 static void zephyr_close(struct gaim_connection *gc) 375 static void zephyr_close(struct gaim_connection *gc)
259 { 376 {
377 g_list_foreach(pending_zloc_names, (GFunc)g_free, NULL);
378 g_list_free(pending_zloc_names);
260 /* should probably write .anyone, but eh. we all use gaim exclusively, right? :-P */ 379 /* should probably write .anyone, but eh. we all use gaim exclusively, right? :-P */
261 if (nottimer) 380 if (nottimer)
262 gtk_timeout_remove(nottimer); 381 gtk_timeout_remove(nottimer);
263 nottimer = 0; 382 nottimer = 0;
264 if (loctimer) 383 if (loctimer)
273 static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { } 392 static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { }
274 static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { } 393 static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { }
275 394
276 static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) { 395 static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) {
277 ZNotice_t notice; 396 ZNotice_t notice;
397 char *buf;
398 char *sig;
399
400 sig = ZGetVariable("zwrite-signature");
401 if (!sig) {
402 sig = g_get_real_name();
403 }
404 buf = g_strdup_printf("%s%c%s", sig, '\0', im);
278 405
279 bzero((char *)&notice, sizeof(notice)); 406 bzero((char *)&notice, sizeof(notice));
280 notice.z_kind = ACKED; 407 notice.z_kind = ACKED;
281 notice.z_port = 0; 408 notice.z_port = 0;
282 notice.z_opcode = ""; 409 notice.z_opcode = "";
283 notice.z_class = "MESSAGE"; 410 notice.z_class = "MESSAGE";
284 notice.z_class_inst = "PERSONAL"; 411 notice.z_class_inst = "PERSONAL";
285 notice.z_sender = 0; 412 notice.z_sender = 0;
286 notice.z_recipient = who; 413 notice.z_recipient = who;
287 notice.z_default_format = 414 notice.z_default_format =
288 "Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\n$message"; 415 "Class $class, Instance $instance:\n"
289 notice.z_message_len = strlen(im) + 1; 416 "To: @bold($recipient) at $time $date\n"
290 notice.z_message = im; 417 "From: @bold($1) <$sender>\n\n$2";
418 notice.z_message_len = strlen(im) + strlen(sig) + 4;
419 notice.z_message = buf;
291 ZSendNotice(&notice, ZAUTH); 420 ZSendNotice(&notice, ZAUTH);
421 g_free(buf);
292 } 422 }
293 423
294 static struct prpl *my_protocol = NULL; 424 static struct prpl *my_protocol = NULL;
295 425
296 void zephyr_init(struct prpl *ret) 426 void zephyr_init(struct prpl *ret)
300 ret->login = zephyr_login; 430 ret->login = zephyr_login;
301 ret->close = zephyr_close; 431 ret->close = zephyr_close;
302 ret->add_buddy = zephyr_add_buddy; 432 ret->add_buddy = zephyr_add_buddy;
303 ret->remove_buddy = zephyr_remove_buddy; 433 ret->remove_buddy = zephyr_remove_buddy;
304 ret->send_im = zephyr_send_im; 434 ret->send_im = zephyr_send_im;
435 ret->get_info = zephyr_zloc;
436 ret->normalize = zephyr_normalize;
437 ret->buddy_menu = zephyr_buddy_menu;
305 438
306 my_protocol = ret; 439 my_protocol = ret;
307 } 440 }
308 441
309 char *gaim_plugin_init(GModule *handle) 442 char *gaim_plugin_init(GModule *handle)