Mon, 14 Oct 2002 07:47:51 +0000
[gaim-migrate @ 3824]
Adds an option for unread mail notification for AIM over oscar. Yippy.
This involves making a connection to the email AIM servers (parallel to
chatnav, bos, auth, ads, etc.). Also added were functions n' stuff to
handle getting mail status updates.
AIM does this in a very silly way. They only tell you how many messages
you have when you sign on, so I had to change connection_has_mail so it
will just say "bleh has new mail," without saying the number of new
messages.
Also, I haven't really looked into having you auto-login to webmail,
though it is possible. This is good for now.
Oh, and since I'm sure people will ask... AIM screen names come with an
email account @netscape.net. You have to sign in to netscape.net to
activate it.
| 3694 | 1 | /* |
| 2 | * Family 0x0018 - Email notification | |
| 3 | * | |
| 4 | * Used for being alerted when the email address(es) associated with | |
| 5 | * your screen name get new electronic-m. For normal AIM accounts, you | |
| 6 | * get the email address screenname@netscape.net. AOL accounts have | |
| 7 | * screenname@aol.com, and can also activate a netscape.net account. | |
| 8 | * | |
| 9 | */ | |
| 10 | ||
| 11 | #define FAIM_INTERNAL | |
| 12 | #include <aim.h> | |
| 13 | ||
| 14 | /* | |
| 15 | * Subtype 0x0006 - Request information about your email account | |
| 16 | */ | |
| 17 | faim_export int aim_email_sendcookies(aim_session_t *sess, aim_conn_t *conn) | |
| 18 | { | |
| 19 | aim_frame_t *fr; | |
| 20 | aim_snacid_t snacid; | |
| 21 | ||
| 22 | if (!sess || !conn) | |
| 23 | return -EINVAL; | |
| 24 | ||
| 25 | if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+16+16))) | |
| 26 | return -ENOMEM; | |
| 27 | snacid = aim_cachesnac(sess, 0x0018, 0x0006, 0x0000, NULL, 0); | |
| 28 | aim_putsnac(&fr->data, 0x0018, 0x0006, 0x0000, snacid); | |
| 29 | ||
| 30 | /* Number of cookies to follow */ | |
| 31 | aimbs_put16(&fr->data, 0x0002); | |
| 32 | ||
| 33 | /* Cookie */ | |
| 34 | aimbs_put16(&fr->data, 0x5d5e); | |
| 35 | aimbs_put16(&fr->data, 0x1708); | |
| 36 | aimbs_put16(&fr->data, 0x55aa); | |
| 37 | aimbs_put16(&fr->data, 0x11d3); | |
| 38 | aimbs_put16(&fr->data, 0xb143); | |
| 39 | aimbs_put16(&fr->data, 0x0060); | |
| 40 | aimbs_put16(&fr->data, 0xb0fb); | |
| 41 | aimbs_put16(&fr->data, 0x1ecb); | |
| 42 | ||
| 43 | /* Cookie */ | |
| 44 | aimbs_put16(&fr->data, 0xb380); | |
| 45 | aimbs_put16(&fr->data, 0x9ad8); | |
| 46 | aimbs_put16(&fr->data, 0x0dba); | |
| 47 | aimbs_put16(&fr->data, 0x11d5); | |
| 48 | aimbs_put16(&fr->data, 0x9f8a); | |
| 49 | aimbs_put16(&fr->data, 0x0060); | |
| 50 | aimbs_put16(&fr->data, 0xb0ee); | |
| 51 | aimbs_put16(&fr->data, 0x0631); | |
| 52 | ||
| 53 | aim_tx_enqueue(sess, fr); | |
| 54 | ||
| 55 | return 0; | |
| 56 | } | |
| 57 | ||
| 58 | ||
| 59 | /* | |
| 60 | * Subtype 0x0007 - Receive information about your email account | |
| 61 | * So I don't even know if you can have 2 different 16 byte keys, | |
| 62 | * but this is coded so it will handle that, and handle it well. | |
| 63 | */ | |
| 64 | static int parseinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) | |
| 65 | { | |
| 66 | aim_rxcallback_t userfunc; | |
| 67 | struct aim_emailinfo *new; | |
| 68 | aim_tlvlist_t *tlvlist; | |
| 69 | fu8_t *cookie8, *cookie16; | |
| 70 | ||
| 71 | cookie8 = aimbs_getraw(bs, 8); /* Possibly the code used to log you in to mail? */ | |
| 72 | cookie16 = aimbs_getraw(bs, 16); /* Mail cookie sent above */ | |
| 73 | ||
| 74 | /* See if we already have some info associated with this cookie */ | |
| 75 | for (new=sess->emailinfo; (new && strncmp(cookie16, new->cookie16, 16)); new=new->next); | |
| 76 | if (new) { | |
| 77 | /* Free some of the old info, if existant */ | |
| 78 | if (new->cookie8) free(new->cookie8); | |
| 79 | if (new->cookie16) free(new->cookie16); | |
| 80 | if (new->url) free(new->url); | |
| 81 | if (new->domain) free(new->domain); | |
| 82 | } else { | |
| 83 | /* We don't already have info, so create a new struct for it */ | |
| 84 | if (!(new = malloc(sizeof(struct aim_emailinfo)))) | |
| 85 | return -ENOMEM; | |
| 86 | ||
| 87 | new->next = sess->emailinfo; | |
| 88 | sess->emailinfo = new; | |
| 89 | } | |
| 90 | ||
| 91 | new->cookie8 = cookie8; | |
| 92 | new->cookie16 = cookie16; | |
| 93 | new->url = NULL; | |
| 94 | new->nummsgs = 0; | |
| 95 | new->unread = 0; | |
| 96 | new->domain = NULL; | |
| 97 | new->flag = 0; | |
| 98 | ||
| 99 | aimbs_get16(bs); /* Number of TLVs to follow */ | |
| 100 | tlvlist = aim_readtlvchain(bs); | |
| 101 | ||
| 102 | new->url = aim_gettlv_str(tlvlist, 0x0007, 1); | |
| 103 | new->nummsgs = aim_gettlv16(tlvlist, 0x0080, 1); | |
| 104 | new->unread = aim_gettlv8(tlvlist, 0x0081, 1); | |
| 105 | new->domain = aim_gettlv_str(tlvlist, 0x0082, 1); | |
| 106 | new->flag = aim_gettlv16(tlvlist, 0x0084, 1); | |
| 107 | ||
| 108 | if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) | |
| 109 | return userfunc(sess, rx, new); | |
| 110 | ||
| 111 | return 0; | |
| 112 | } | |
| 113 | ||
| 114 | /* | |
| 115 | * Subtype 0x0016 - Send something or other | |
| 116 | */ | |
| 117 | faim_export int aim_email_activate(aim_session_t *sess, aim_conn_t *conn) | |
| 118 | { | |
| 119 | aim_frame_t *fr; | |
| 120 | aim_snacid_t snacid; | |
| 121 | ||
| 122 | if (!sess || !conn) | |
| 123 | return -EINVAL; | |
| 124 | ||
| 125 | if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+16))) | |
| 126 | return -ENOMEM; | |
| 127 | snacid = aim_cachesnac(sess, 0x0018, 0x0016, 0x0000, NULL, 0); | |
| 128 | aim_putsnac(&fr->data, 0x0018, 0x0016, 0x0000, snacid); | |
| 129 | ||
| 130 | /* I would guess this tells AIM that you want updates for your mail accounts */ | |
| 131 | /* ...but I really have no idea */ | |
| 132 | aimbs_put8(&fr->data, 0x02); | |
| 133 | aimbs_put32(&fr->data, 0x04000000); | |
| 134 | aimbs_put32(&fr->data, 0x04000000); | |
| 135 | aimbs_put32(&fr->data, 0x04000000); | |
| 136 | aimbs_put32(&fr->data, 0x00000000); | |
| 137 | ||
| 138 | aim_tx_enqueue(sess, fr); | |
| 139 | ||
| 140 | return 0; | |
| 141 | } | |
| 142 | ||
| 143 | static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) | |
| 144 | { | |
| 145 | ||
| 146 | if (snac->subtype == 0x0007) | |
| 147 | return parseinfo(sess, mod, rx, snac, bs); | |
| 148 | ||
| 149 | return 0; | |
| 150 | } | |
| 151 | ||
| 152 | static void email_shutdown(aim_session_t *sess, aim_module_t *mod) | |
| 153 | { | |
| 154 | while (sess->emailinfo) { | |
| 155 | struct aim_emailinfo *tmp = sess->emailinfo; | |
| 156 | sess->emailinfo = sess->emailinfo->next; | |
| 157 | if (tmp->cookie16) free(tmp->cookie16); | |
| 158 | if (tmp->cookie8) free(tmp->cookie8); | |
| 159 | if (tmp->url) free(tmp->url); | |
| 160 | if (tmp->domain) free(tmp->domain); | |
| 161 | free(tmp); | |
| 162 | } | |
| 163 | ||
| 164 | return; | |
| 165 | } | |
| 166 | ||
| 167 | faim_internal int email_modfirst(aim_session_t *sess, aim_module_t *mod) | |
| 168 | { | |
| 169 | ||
| 170 | mod->family = 0x0018; | |
| 171 | mod->version = 0x0001; | |
| 172 | mod->toolid = 0x0010; | |
| 173 | mod->toolversion = 0x0629; | |
| 174 | mod->flags = 0; | |
| 175 | strncpy(mod->name, "email", sizeof(mod->name)); | |
| 176 | mod->snachandler = snachandler; | |
| 177 | mod->shutdown = email_shutdown; | |
| 178 | ||
| 179 | return 0; | |
| 180 | } |