Mercurial > pidgin
diff src/protocols/jabber/jutil.c @ 7014:67c4e9d39242
[gaim-migrate @ 7577]
Here it is, the bulk of the new Jabber prpl.
Left to do:
- Implement registration
- Implement password changing
- Keep track of conversation threads (since I apparently have to)
- Fix the bugs that always magically appear in code after I commit
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Mon, 29 Sep 2003 15:23:19 +0000 |
parents | 988485669631 |
children | 1930e3d00ecd |
line wrap: on
line diff
--- a/src/protocols/jabber/jutil.c Mon Sep 29 13:00:55 2003 +0000 +++ b/src/protocols/jabber/jutil.c Mon Sep 29 15:23:19 2003 +0000 @@ -1,295 +1,185 @@ -/* -------------------------------------------------------------------------- - * - * License +/* + * gaim - Jabber Protocol Plugin * - * The contents of this file are subject to the Jabber Open Source License - * Version 1.0 (the "JOSL"). You may not copy or use this file, in either - * source code or executable form, except in compliance with the JOSL. You - * may obtain a copy of the JOSL at http://www.jabber.org/ or at - * http://www.opensource.org/. + * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> * - * Software distributed under the JOSL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the JOSL - * for the specific language governing rights and limitations under the - * JOSL. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyrights - * - * Portions created by or assigned to Jabber.com, Inc. are - * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact - * information for Jabber.com, Inc. is available at http://www.jabber.com/. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Portions Copyright (c) 1998-1999 Jeremie Miller. - * - * Acknowledgements - * - * Special thanks to the Jabber Open Source Contributors for their - * suggestions and support of Jabber. - * - * Alternatively, the contents of this file may be used under the terms of the - * GNU General Public License Version 2 or later (the "GPL"), in which case - * the provisions of the GPL are applicable instead of those above. If you - * wish to allow use of your version of this file only under the terms of the - * GPL and not to allow others to use your version of this file under the JOSL, - * indicate your decision by deleting the provisions above and replace them - * with the notice and other provisions required by the GPL. If you do not - * delete the provisions above, a recipient may use your version of this file - * under either the JOSL or the GPL. - * - * - * --------------------------------------------------------------------------*/ + */ +#include "internal.h" +#include "server.h" + +#include "presence.h" +#include "jutil.h" -#include "lib.h" +time_t str_to_time(const char *timestamp) +{ + struct tm t; + time_t retval = 0; + char buf[32]; + char *c; + int tzoff = 0; -#ifdef _WIN32 -#include "win32dep.h" -#endif + time(&retval); + localtime_r(&retval, &t); + + snprintf(buf, sizeof(buf), "%s", timestamp); + c = buf; -/* util for making presence packets */ -xmlnode jutil_presnew(int type, char *to, char *status) -{ - xmlnode pres; + /* 4 digit year */ + if(!sscanf(c, "%04d", &t.tm_year)) return 0; + c+=4; + if(*c == '-') + c++; - pres = xmlnode_new_tag("presence"); - switch(type) - { - case JPACKET__SUBSCRIBE: - xmlnode_put_attrib(pres,"type","subscribe"); - break; - case JPACKET__UNSUBSCRIBE: - xmlnode_put_attrib(pres,"type","unsubscribe"); - break; - case JPACKET__SUBSCRIBED: - xmlnode_put_attrib(pres,"type","subscribed"); - break; - case JPACKET__UNSUBSCRIBED: - xmlnode_put_attrib(pres,"type","unsubscribed"); - break; - case JPACKET__PROBE: - xmlnode_put_attrib(pres,"type","probe"); - break; - case JPACKET__UNAVAILABLE: - xmlnode_put_attrib(pres,"type","unavailable"); - break; - case JPACKET__INVISIBLE: - xmlnode_put_attrib(pres,"type","invisible"); - break; - } - if(to != NULL) - xmlnode_put_attrib(pres,"to",to); - if(status != NULL) - xmlnode_insert_cdata(xmlnode_insert_tag(pres,"status"),status,strlen(status)); + t.tm_year -= 1900; + + /* 2 digit month */ + if(!sscanf(c, "%02d", &t.tm_mon)) return 0; + c+=2; + if(*c == '-') + c++; + + t.tm_mon -= 1; - return pres; -} + /* 2 digit day */ + if(!sscanf(c, "%02d", &t.tm_mday)) return 0; + c+=2; + if(*c == 'T') { /* we have more than a date, keep going */ + c++; /* skip the "T" */ -/* util for making IQ packets */ -xmlnode jutil_iqnew(int type, char *ns) -{ - xmlnode iq; + /* 2 digit hour */ + if(sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec)) { + int tzhrs, tzmins; + c+=8; + if(*c == '.') /* dealing with precision we don't care about */ + c += 4; - iq = xmlnode_new_tag("iq"); - switch(type) - { - case JPACKET__GET: - xmlnode_put_attrib(iq,"type","get"); - break; - case JPACKET__SET: - xmlnode_put_attrib(iq,"type","set"); - break; - case JPACKET__RESULT: - xmlnode_put_attrib(iq,"type","result"); - break; - case JPACKET__ERROR: - xmlnode_put_attrib(iq,"type","error"); - break; - } - xmlnode_put_attrib(xmlnode_insert_tag(iq,"query"),"xmlns",ns); - - return iq; -} - -/* util for making message packets */ -xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body) -{ - xmlnode msg; + if((*c == '+' || *c == '-') && + sscanf(c+1, "%02d:%02d", &tzhrs, &tzmins)) { + tzoff = tzhrs*60*60 + tzmins*60; + if(*c == '+') + tzoff *= -1; + } - msg = xmlnode_new_tag("message"); - xmlnode_put_attrib (msg, "type", type); - xmlnode_put_attrib (msg, "to", to); - - if (subj) - { - xmlnode_insert_cdata (xmlnode_insert_tag (msg, "subject"), subj, strlen (subj)); +#ifdef HAVE_TM_GMTOFF + tzoff += t.tm_gmtoff; +#else +# ifdef HAVE_TIMEZONE + tzset(); /* making sure */ + tzoff -= timezone; +# endif +#endif + } } - - xmlnode_insert_cdata (xmlnode_insert_tag (msg, "body"), body, strlen (body)); + retval = mktime(&t); - return msg; -} + retval += tzoff; -/* util for making stream packets */ -xmlnode jutil_header(char* xmlns, char* server) -{ - xmlnode result; - if ((xmlns == NULL)||(server == NULL)) - return NULL; - result = xmlnode_new_tag("stream:stream"); - xmlnode_put_attrib(result, "xmlns:stream", "http://etherx.jabber.org/streams"); - xmlnode_put_attrib(result, "xmlns", xmlns); - xmlnode_put_attrib(result, "to", server); - - return result; + return retval; } -/* returns the priority on a presence packet */ -int jutil_priority(xmlnode x) -{ - char *str; - int p; - - if(x == NULL) - return -1; - - if(xmlnode_get_attrib(x,"type") != NULL) - return -1; - - x = xmlnode_get_tag(x,"priority"); - if(x == NULL) - return 0; - - str = xmlnode_get_data((x)); - if(str == NULL) - return 0; - - p = atoi(str); - if(p >= 0) - return p; - else - return 0; -} - -void jutil_tofrom(xmlnode x) -{ - char *to, *from; - - to = xmlnode_get_attrib(x,"to"); - from = xmlnode_get_attrib(x,"from"); - xmlnode_put_attrib(x,"from",to); - xmlnode_put_attrib(x,"to",from); -} - -xmlnode jutil_iqresult(xmlnode x) -{ - xmlnode cur; - - jutil_tofrom(x); - - xmlnode_put_attrib(x,"type","result"); - - /* hide all children of the iq, they go back empty */ - for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) - xmlnode_hide(cur); - - return x; -} - -char *jutil_timestamp(void) -{ - time_t t; - struct tm *new_time; - static char timestamp[18]; - int ret; - - t = time(NULL); - - if(t == (time_t)-1) - return NULL; - new_time = gmtime(&t); - - ret = snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900+new_time->tm_year, - new_time->tm_mon+1, new_time->tm_mday, new_time->tm_hour, - new_time->tm_min, new_time->tm_sec); - - if(ret == -1) - return NULL; - - return timestamp; +const char *jabber_get_state_string(int s) { + switch(s) { + case JABBER_STATE_AWAY: + return _("Away"); + break; + case JABBER_STATE_CHAT: + return _("Chatty"); + break; + case JABBER_STATE_XA: + return _("Extended Away"); + break; + case JABBER_STATE_DND: + return _("Do Not Disturb"); + break; + default: + return _("Available"); + break; + } } -void jutil_error(xmlnode x, terror E) +JabberID* +jabber_id_new(const char *str) { - xmlnode err; - char code[4]; + char *at; + char *slash; + + JabberID *jid; - xmlnode_put_attrib(x,"type","error"); - err = xmlnode_insert_tag(x,"error"); + if(!str) + return NULL; - snprintf(code,4,"%d",E.code); - xmlnode_put_attrib(err,"code",code); - if(E.msg != NULL) - xmlnode_insert_cdata(err,E.msg,strlen(E.msg)); + jid = g_new0(JabberID, 1); + + at = strchr(str, '@'); + slash = strchr(str, '/'); - jutil_tofrom(x); -} - -void jutil_delay(xmlnode msg, char *reason) -{ - xmlnode delay; + if(at) { + jid->node = g_strndup(str, at-str); + if(slash) { + jid->domain = g_strndup(at+1, slash-(at+1)); + jid->resource = g_strdup(slash+1); + } else { + jid->domain = g_strdup(at+1); + } + } else { + if(slash) { + jid->domain = g_strndup(str, slash-str); + jid->resource = g_strdup(slash+1); + } else { + jid->domain = g_strdup(str); + } + } - delay = xmlnode_insert_tag(msg,"x"); - xmlnode_put_attrib(delay,"xmlns",NS_DELAY); - xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(msg,"to")); - xmlnode_put_attrib(delay,"stamp",jutil_timestamp()); - if(reason != NULL) - xmlnode_insert_cdata(delay,reason,strlen(reason)); + return jid; } -#define KEYBUF 100 - -char *jutil_regkey(char *key, char *seed) +void +jabber_id_free(JabberID *jid) { - static char keydb[KEYBUF][41]; - static char seeddb[KEYBUF][41]; - static int last = -1; - char *str, strint[32]; - int i; - - /* blanket the keydb first time */ - if(last == -1) - { - last = 0; - memset(&keydb,0,KEYBUF*41); - memset(&seeddb,0,KEYBUF*41); - srand(time(NULL)); - } - - /* creation phase */ - if(key == NULL && seed != NULL) - { - /* create a random key hash and store it */ - sprintf(strint,"%d",rand()); - strcpy(keydb[last],shahash(strint)); - - /* store a hash for the seed associated w/ this key */ - strcpy(seeddb[last],shahash(seed)); - - /* return it all */ - str = keydb[last]; - last++; - if(last == KEYBUF) last = 0; - return str; - } - - /* validation phase */ - str = shahash(seed); - for(i=0;i<KEYBUF;i++) - if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0) - { - seeddb[i][0] = '\0'; /* invalidate this key */ - return keydb[i]; - } - - return NULL; + if(jid) { + if(jid->node) + g_free(jid->node); + if(jid->domain) + g_free(jid->domain); + if(jid->resource) + g_free(jid->resource); + g_free(jid); + } } + +const char *jabber_get_resource(const char *jid) +{ + char *slash; + + slash = strrchr(jid, '/'); + if(slash) + return slash+1; + else + return NULL; +} + +char *jabber_get_bare_jid(const char *jid) +{ + char *slash; + slash = strrchr(jid, '/'); + + if(slash) + return g_strndup(jid, slash - jid); + else + return g_strdup(jid); +}