Mercurial > pidgin.yaz
changeset 1054:0b0b4cb53c17
[gaim-migrate @ 1064]
yahoo prpl
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 03 Nov 2000 10:03:53 +0000 |
parents | 864f4aae0b60 |
children | 5a99def38a47 |
files | configure.in plugins/Makefile.am plugins/yay/.cvsignore plugins/yay/AUTHORS plugins/yay/COPYING plugins/yay/ChangeLog plugins/yay/INSTALL plugins/yay/Makefile.am plugins/yay/NEWS plugins/yay/NOTES plugins/yay/README plugins/yay/libyahoo-proto.h plugins/yay/libyahoo.c plugins/yay/libyahoo.h plugins/yay/memtok.c plugins/yay/memtok.h plugins/yay/yay.c |
diffstat | 16 files changed, 5150 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Fri Nov 03 01:33:28 2000 +0000 +++ b/configure.in Fri Nov 03 10:03:53 2000 +0000 @@ -197,6 +197,7 @@ intl/Makefile sounds/Makefile plugins/Makefile + plugins/yay/Makefile pixmaps/Makefile libfaim/Makefile po/Makefile.in
--- a/plugins/Makefile.am Fri Nov 03 01:33:28 2000 +0000 +++ b/plugins/Makefile.am Fri Nov 03 10:03:53 2000 +0000 @@ -4,7 +4,10 @@ $(CC) $(CFLAGS) -I../src -DVERSION=\"$(VERSION)\" -o $@ $< $(LDFLAGS) $(PLUGIN_LIBS) if PLUGINS -plugin_DATA = autorecon.so iconaway.so notify.so spellchk.so lagmeter.so + +SUBDIRS = yay + +plugin_DATA = autorecon.so iconaway.so irc.so notify.so spellchk.so lagmeter.so plugindir = $(libdir)/gaim clean distclean:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/.cvsignore Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,8 @@ +Makefile +Makefile.in +.deps +.libs +libyahoo.lo +memtok.lo +yay.lo +libyahoo.la
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/AUTHORS Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,50 @@ +Primary Authors +--------------- +Nathan Neulinger <nneul@umr.edu> + http://www.umr.edu/~nneul/ + GTK interface and rewrite of protocol handling code + +Supporting Authors +------------------ +Jay Lubomirski <jaylubo@fiam.net> + Work on conferencing support +Gary Godfrey <Gary.Godfrey@amd.com> + Misc. patches to config and cookie parsing +Scott D. Heavner <sdh@po.cwru.edu> + Support for actions, window creation/sizing improvements, etc. +Scott A. Barron <kain224@yahoo.com> + Lots of patches to clean up user interface, using tables, etc. + Support for clicking on mail status icon to open web browser. +Thomas James <tbjames@bellsouth.net> + Patched version of gtkyahoo that had initial http mode support +Roberto Machorro Angoa <rmach@bigfoot.com> + http://www.bigfoot.com/~rmach/ + Misc. suggestions, screenshots, GTK coding assistance + Sample icon code and gtkyahoo icon +Craig Emery <ranec@yahoo.com> + Info on calendar and new mail protocol packets + AIX and other misc. patches + Lots of additional functionality +Douglas Winslow <douglas@min.net> + Prototype code for Yahoo Pager protocol +Jon Keating <jonkeating@norcom2000.com> + Patch for password validation checking +Nicolas Barry <boozai@yahoo.com> + Couple of buffer overrun patches +Keeyeong Tan <encloaking_darkness@yahoo.com> + Custom status window + +Acknowledgements +---------------- +Andreas Plesner Jacobsen <scoof@nerd.dk> + Debian package maintainer +Kurt Granroth <granroth@kde.org> + Grabbed his icons from KBiff for the mail indicator +Mary Hart-Byfield <kimbykitten@yahoo.com> + Windows pager interoperability testing +Timothy Allen <inkumbi@yahoo.com> + Helped diagnose problem with non-encoded userid and password in request + for login cookie. Also problem with no newline on last line of + config file. Numerous xpm suggestions and examples. +Dan Nguyen <nguyend7@cse.msu.edu> + Debian build fixes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/COPYING Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,402 @@ + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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. + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + +The following copyright notice applies to the SHA1 +implementation: + + + Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + All rights reserved. + + This package is an SSL implementation written + by Eric Young (eay@cryptsoft.com). + The implementation was written so as to conform with Netscapes SSL. + + This library is free for commercial and non-commercial use as long as + the following conditions are aheared to. The following conditions + apply to all code found in this distribution, be it the RC4, RSA, + lhash, DES, etc., code; not just the SSL code. The SSL documentation + included with this distribution is covered by the same copyright terms + except that the holder is Tim Hudson (tjh@cryptsoft.com). + + Copyright remains Eric Young's, and as such any Copyright notices in + the code are not to be removed. + If this package is used in a product, Eric Young should be given attribution + as the author of the parts of the library used. + This can be in the form of a textual message at program startup or + in documentation (online or textual) provided with the package. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + "This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com)" + The word 'cryptographic' can be left out if the rouines from the library + being used are not cryptographic related :-). + 4. If you include any Windows specific code (or a derivative thereof) from + the apps directory (application code) you must include an acknowledgement: + "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + + THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + The licence and distribution terms for any publically available version or + derivative of this code cannot be changed. i.e. this code cannot simply be + copied and put under another distribution licence + [including the GNU Public Licence.]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/ChangeLog Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,18 @@ +libyahoo 0.17: + Initial introduction, corresponds to development version + of gtkyahoo. + Added some NULL pointer checks to yahoo_array2list and yahoo_cmd_decline_conf + Added new memtok utility function (see memtok.c) and used it in some of the + conference packet parsing routines + Small #include changes for building under Solaris + Added NOTES file as small beginnings of documentation process + Cleaned up compiler warnings when building under Solaris + Started adding support for getting address book entries of Yahoo! buddies + Currently they're successfully retrieved but not kept anywhere useful + All addresses can now be retrieved into a context as follows: + struct yahoo_address = structure with name, phone numbers... + context->address_count = number of addresses + context->addresses = pointer to first address + I currently DO NOT call yahoo_fetchaddresses from within yahoo_init, I think it should be optional + See yahoo_free_addresses for how to iterate over addresses + Added patch for removebuddy + http proxy support
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/INSTALL Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,76 @@ +Simple install procedure +======================== + + % gzip -cd gtkyahoo-<version>.tar.gz | tar xvf - # unpack the sources + % cd gtkyahoo-<version> # change to the toplevel directory + % ./configure # run the `configure' script + % make # build GTKYahoo + [ Become root if necessary ] + % make install # install GTKYahoo + % gtkyahoo # run gtkyahoo once + % vi $HOME/.gtkyahoo/gtkyahoorc # update/create config file + +NOTE - OpenBSD (and possibly other *BSD) users might need to use gmake +instead of make when compiling this software. + +The Nitty-Gritty +================ + +The 'configure' script can be given a number of options to enable +and disable various features. For a complete list, type: + + ./configure --help + +A few of the more important ones: + +* --prefix=PREFIX install architecture-independent files in PREFIX + [ Defaults to /usr/local ] + +Options can be given to the compiler and linker by setting +environment variables before running configure. A few of the more +important ones: + + CC : The C compiler to use + CPPFLAGS : Flags for the C preprocesser such as -I and -D + CFLAGS : C compiler flags + +The most important use of this is to set the +optimization/debugging flags. For instance, to compile with no +debugging information at all, run configure as: + + CFLAGS=-O2 ./configure # Bourne compatible shells (sh/bash/zsh) + +or, + + setenv CFLAGS -O2 ; ./configure # csh and variants + + +Installation directories +======================== + +The location of the installed files is determined by the --prefix +and --exec-prefix options given to configure. There are also more +detailed flags to control individual directories. However, the +use of these flags is not tested. + + +BSD build instructions +====================== + +BSD users might need to use gmake instead of make when compiling this +software. + + +Debian build instructions +========================= + +Requires fakeroot and debhelper packages installed. + +% fakeroot +% debian/rules binary + +This will create a gtkyahoo-<version>.deb file in the higher +directory, not <version> stands for the version number. + +[become root] +% dpkg -i gtkyahoo-<version>.deb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/Makefile.am Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,10 @@ +CFLAGS = -g -O2 -I../../src -I../../libfaim/faim -I../../libfaim $(GTK_CFLAGS) +LIBS = $(GTK_LIBS) + +pkgdir = $(libdir)/gaim +pkg_LTLIBRARIES = libyahoo.la + +libyahoo_la_SOURCES = libyahoo.c memtok.c yay.c + +EXTRA_DIST = libyahoo-proto.h libyahoo.h memtok.h \ + AUTHORS COPYING ChangeLog INSTALL NEWS NOTES README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/NOTES Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,61 @@ +Small scenario notes by Craig: + +Here's the scenario: + +The pager does the normal cookie retrieval thing with +http://msg.edit.yahoo.com:80/config/ncclogin?.src=bl&login=<USERID>&passwd=<PASSWORD>0&n=1&t=1 + +which gives you the cookies +(Y=n=<NSUBCOOKIE>&l=<LSUBCOOKIE> is all you need to keep). + +( I was thinking that we might include a configurable option to "put" this into Netscape's cookies file +just like the Win32 version does. ) + +Then: + +http://msg.edit.yahoo.com:80/config/get_buddylist?.src=bl&.l=<USERID> + +if given the cookies +Y=v=1&n=<NSUBCOOKIE>&l=<LSUBCOOKIE> (where <NSUBCOOKIE> and <LSUBCOOKIE> were retrieved from ncclogin) +gives you the buddies list as: + +BEGIN BUDDYLIST +<GROUP>:ID[,IDn]* +END BUDDYLIST +BEGIN IGNORELIST + +END IGNORELIST +BEGIN IDENTITIES +<PRIMARYID>[,<OTHERID>]* +END IDENTITIES +Mail=<UNREADMAIL> +Login=<PRIMARYID> + +You can get details of the people in your Yahoo! Address book for which you have mentioned their Messenger ID with: + +http://uk.address.yahoo.com:80/yab/uk/yab?v=PG&A=s +with cookies Y=v=1&n=<NSUBCOOKIE>&l=<LSUBCOOKIE> +gives: + +1^I +<ID>:<FIRSTNAME>^I<LASTNAME>^I<EMAILNICKNAME>^I<EMAIL>^I<HOMEPHONE>^I<WORKPHONE>^I[01]^I<ENTRYID> + +(the [01] is 0 if the entry's Primary phone is "Home" +and 1 if it's "Work") + +so for me it **might** be: + +ranec:Craig^IEmery^Iranec@yahoo.com^I+44 UK work^I+44 UK home^I1^I123 + +( I **really** want to get these entries retreived by libyahoo so I can use them as tool-tips on your friend's id's just like the +Win32 version does. ) + +Anyway after loging in and getting the buddies list and your address book entries, it periodically opens a connection to: + +http://http.pager.yahoo.com:80/notify/ + +and I don't know the details of this traffic 'cause I've got no packet sniffing on Win23 (NT actually). + +Has anyone else out there traced any of the "notify" traffic? + +All I need is this and I can get GtkYahoo working entirely over HTTP (even HTTP proxies) and firewalls become irrelevant!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/README Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,59 @@ +Introduction: +------------- +This is GTKYahoo, a GPL'd GTK Yahoo! Pager client. It is functional +enough to carry on normal conversations. New features, and additional +functionality is being added quite frequently. + +Please send me patches/fixes/additions/suggestions... Any help is +appreciated. + +I _HIGHLY_ suggest reading the ChangeLog and other files in here to get +some details on what is going on with the program, etc. + +This software is not supported or sponsored in any way by Yahoo!. + +Where to get: +------------- +Home Page: http://www.unixtools.org/gtkyahoo/ +Download Area: http://www.unixtools.org/gtkyahoo/dist/ +Anon-CVS: + Root: :pserver:cvs@cvs.unixtools.org:/cvsroot-gtkyahoo + Password: cvs + Module: gtkyahoo + +Usage notes: +------------ +The first time you run GTKYahoo it will create a configuration directory +and config file. Edit it prior to running the program again. + +Look at the sample gtkyahoorc file for info on other options. Note, many +of the features are unimplemented at the moment. + +Debugging options are available in the config file, syntax is: + + debug "keyword" level + +i.e. + + debug "yahoolib" 1 + +Available keywords include: + packets: enables tracing of received packets + yahoolib: enables debugging of yahoolib actions + sendraw: enables the sendraw facility + +Development notes: +------------------ +This program makes use of the cfunctions program to build some of it's +header files. This is only done in response to issuing "make proto". +The cfunctions tool is available from the URL: + + http://www.hayamasa.demon.co.uk/cfunctions + +The yahoolib files can be pulled out and used to implement the pager +protocol. They are not documented however. The basic functionality of the library is that you give it a pointer to a buffer area, and the size of the buffer, +and it will return you a raw packet if the buffer contains one. The actual +I/O with the server is up to you. + +Other suggested packages include: + bison, flex, ElectricFence, cvs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/libyahoo-proto.h Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,104 @@ +/* This is a Cfunctions (version 0.24) generated header file. + Cfunctions is a free program for extracting headers from C files. + Get Cfunctions from `http://www.hayamasa.demon.co.uk/cfunctions'. */ + +/* This file was generated with: +`cfunctions -w LIBYAHOO_PROTO -o ./libyahoo-proto.h' */ +#ifndef CFH_LIBYAHOO_PROTO +#define CFH_LIBYAHOO_PROTO + +unsigned int yahoo_makeint(unsigned char *data); +char **yahoo_list2array(char *buff); +void yahoo_arraykill(char **array); +char *yahoo_array2list(char **array); +struct yahoo_context *yahoo_init(char *user, char *password, + + struct yahoo_options *options); +void yahoo_free_context(struct yahoo_context *ctx); +char *yahoo_get_status_string(int statuscode); +char *yahoo_get_status_append(int statuscode); +char *yahoo_get_service_string(int servicecode); +int yahoo_fetchcookies(struct yahoo_context *ctx); +int yahoo_add_buddy(struct yahoo_context *ctx, char *addid, char *active_id, + char *group, char *msg); +int yahoo_remove_buddy(struct yahoo_context *ctx, char *addid, + char *active_id, char *group, char *msg); +int yahoo_get_config(struct yahoo_context *ctx); +int yahoo_cmd_logon(struct yahoo_context *ctx, unsigned int initial_status); +int yahoo_connect(struct yahoo_context *ctx); +int yahoo_sendcmd_http(struct yahoo_context *ctx, + + struct yahoo_rawpacket *pkt); +int yahoo_sendcmd(struct yahoo_context *ctx, int service, char *active_nick, + char *content, unsigned int msgtype); +int yahoo_cmd_ping(struct yahoo_context *ctx); +int yahoo_cmd_idle(struct yahoo_context *ctx); +int yahoo_cmd_sendfile(struct yahoo_context *ctx, char *active_user, + char *touser, char *msg, char *filename); +int yahoo_cmd_msg(struct yahoo_context *ctx, char *active_user, char *touser, + + char *msg); +int yahoo_cmd_msg_offline(struct yahoo_context *ctx, char *active_user, + char *touser, char *msg); +int yahoo_cmd_set_away_mode(struct yahoo_context *ctx, int status, char *msg); +int yahoo_cmd_set_back_mode(struct yahoo_context *ctx, int status, char *msg); +int yahoo_cmd_activate_id(struct yahoo_context *ctx, char *newid); +int yahoo_cmd_user_status(struct yahoo_context *ctx); +int yahoo_cmd_logoff(struct yahoo_context *ctx); +int yahoo_cmd_start_conf(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *msg, int type); +int yahoo_cmd_conf_logon(struct yahoo_context *ctx, char *conf_id, + + char *host, char **userlist); +int yahoo_cmd_decline_conf(struct yahoo_context *ctx, char *conf_id, + char *host, char **userlist, char *msg); +int yahoo_cmd_conf_logoff(struct yahoo_context *ctx, char *conf_id, + + char **userlist); +int yahoo_cmd_conf_invite(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *invited_user, char *msg); +int yahoo_cmd_conf_msg(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *msg); +void yahoo_free_rawpacket(struct yahoo_rawpacket *pkt); +void yahoo_free_packet(struct yahoo_packet *pkt); +void yahoo_free_idstatus(struct yahoo_idstatus *idstatus); +struct yahoo_packet *yahoo_parsepacket(struct yahoo_context *ctx, + + struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_ping(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_newmail(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_grouprename(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_conference_invite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_conference_decline(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_conference_addinvite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_conference_msg(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_conference_user(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_filetransfer(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_calendar(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_chatinvite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_newcontact(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_status(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_message(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_parsepacket_message_offline(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt); +int yahoo_getdata(struct yahoo_context *ctx); +struct yahoo_rawpacket *yahoo_getpacket(struct yahoo_context *ctx); +int yahoo_isbuddy(struct yahoo_context *ctx, const char *id); +void yahoo_freeaddressbook(struct yahoo_context *ctx); +int yahoo_fetchaddressbook(struct yahoo_context *ctx); + +#endif /* CFH_LIBYAHOO_PROTO */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/libyahoo.c Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,3600 @@ +/* + Yahoo Pager Client Library + + This code is based on code by Douglas Winslow. The original info from + his code is listed below. This code has taken his code and has been + altered to my naming and coding conventions and has been made more + usable as a library of routines. + + -- Nathan Neulinger <nneul@umr.edu> + */ + +/* + Yahoo Pager Client Emulator Pro - yppro.c + A basic reference implementation + Douglas Winslow <douglas@min.net> + Tue Sep 1 02:28:21 EDT 1998 + Version 2, Revision 2 + Known to compile on Linux 2.0, FreeBSD 2.2, and BSDi 3.0. + hi to aap bdc drw jfn jrc mm mcd [cejn]b #cz and rootshell + + Finally! + Yahoo finally patched their server-side, and things will be getting + back to "normal". I will continue to maintain this code as long as + there is interest for it. Since Yahoo will be discontinuing YPNS1.1 + login support shortly, I've upgraded this client to do YPNS1.2. You + *must* have a password to pass authentication to the pager server. + This authentication is done by a weird HTTP cookie method. + + This code is distributed under the GNU General Public License (GPL) + */ + +#include "config.h" +#include <stdio.h> +#include <netdb.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#if defined(WITH_GTK) +#include <gtk/gtk.h> +#endif +#include <unistd.h> +#if defined(HAVE_STRINGS_H) +#include <strings.h> +#endif +#if defined(HAVE_STRING_H) +#include <string.h> +#endif +#include <ctype.h> +#include "libyahoo.h" +#ifdef HAVE_DMALLOC +#include "dmalloc.h" +#else +#include <stdlib.h> +#endif + +#include "memtok.h" + +/* allow libyahoo to be used without gtkyahoo's debug support */ +#ifdef ENABLE_LIBYAHOO_DEBUG +#include "libyahoo-debug.h" +#else +static void yahoo_dbg_Print(char *tmp, ...) +{ +} + +#define yahoo_dbg_NullCheck(x) ((x)?(x):("[NULL]")) +#endif + +/* remap functions to gtk versions */ +#if defined(WITH_GTK) +#define malloc g_malloc +#define free g_free +#define calloc(x,y) g_malloc0((x)*(y)) +#endif + +#if (!defined(TRUE) || !defined(FALSE)) +# define TRUE 1 +# define FALSE 0 +#endif + +/* Define a quick shortcut function to free a pointer and set it to null */ +#define FREE(x) if (x) { free(x); x=NULL; } + +#if defined(WITH_SOCKS4) +void SOCKSinit(char *argv0); +#endif + +/* pager server host */ +#define YAHOO_PAGER_HOST "cs.yahoo.com" +#define YAHOO_PAGER_PORT 5050 +/* pager server host for http connections */ +#define YAHOO_PAGER_HTTP_HOST "http.pager.yahoo.com" +#define YAHOO_PAGER_HTTP_PORT 80 +/* authentication/login host */ +#define YAHOO_AUTH_HOST "msg.edit.yahoo.com" +#define YAHOO_AUTH_PORT 80 +/* buddy/identity/config host */ +#define YAHOO_DATA_HOST YAHOO_AUTH_HOST +#define YAHOO_DATA_PORT 80 +/* Address book host */ +#define YAHOO_ADDRESS_HOST "uk.address.yahoo.com" +#define YAHOO_ADDRESS_PORT 80 + +/* User agent to use for HTTP connections */ +/* It needs to have Mozilla/4 in it, otherwise it fails */ +#ifndef VERSION +#define VERSION "1.0" +#endif +#define YAHOO_USER_AGENT "Mozilla/4.6 (libyahoo/" VERSION ")" + +#define YAHOO_PROTOCOL_HEADER "YPNS2.0" + +/* + * Routines and data private to this library, should not be directly + * accessed outside of these routines. + */ + +/* Service code labels for debugging output */ +static struct yahoo_idlabel yahoo_service_codes[] = { + {YAHOO_SERVICE_LOGON, "Pager Logon"}, + {YAHOO_SERVICE_LOGOFF, "Pager Logoff"}, + {YAHOO_SERVICE_ISAWAY, "Is Away"}, + {YAHOO_SERVICE_ISBACK, "Is Back"}, + {YAHOO_SERVICE_IDLE, "Idle"}, + {YAHOO_SERVICE_MESSAGE, "Message"}, + {YAHOO_SERVICE_IDACT, "Activate Identity"}, + {YAHOO_SERVICE_IDDEACT, "Deactivate Identity"}, + {YAHOO_SERVICE_MAILSTAT, "Mail Status"}, + {YAHOO_SERVICE_USERSTAT, "User Status"}, + {YAHOO_SERVICE_NEWMAIL, "New Mail"}, + {YAHOO_SERVICE_CHATINVITE, "Chat Invitation"}, + {YAHOO_SERVICE_CALENDAR, "Calendar Reminder"}, + {YAHOO_SERVICE_NEWPERSONALMAIL, "New Personals Mail"}, + {YAHOO_SERVICE_NEWCONTACT, "New Friend"}, + {YAHOO_SERVICE_GROUPRENAME, "Group Renamed"}, + {YAHOO_SERVICE_ADDIDENT, "Add Identity"}, + {YAHOO_SERVICE_ADDIGNORE, "Add Ignore"}, + {YAHOO_SERVICE_PING, "Ping"}, + {YAHOO_SERVICE_SYSMESSAGE, "System Message"}, + {YAHOO_SERVICE_CONFINVITE, "Conference Invitation"}, + {YAHOO_SERVICE_CONFLOGON, "Conference Logon"}, + {YAHOO_SERVICE_CONFDECLINE, "Conference Decline"}, + {YAHOO_SERVICE_CONFLOGOFF, "Conference Logoff"}, + {YAHOO_SERVICE_CONFMSG, "Conference Message"}, + {YAHOO_SERVICE_CONFADDINVITE, "Conference Additional Invitation"}, + {YAHOO_SERVICE_CHATLOGON, "Chat Logon"}, + {YAHOO_SERVICE_CHATLOGOFF, "Chat Logoff"}, + {YAHOO_SERVICE_CHATMSG, "Chat Message"}, + {YAHOO_SERVICE_GAMELOGON, "Game Logon"}, + {YAHOO_SERVICE_GAMELOGOFF, "Game Logoff"}, + {YAHOO_SERVICE_FILETRANSFER, "File Transfer"}, + {YAHOO_SERVICE_PASSTHROUGH2, "Passthrough 2"}, + {0, NULL} +}; + +/* Status codes */ +static struct yahoo_idlabel yahoo_status_codes[] = { + {YAHOO_STATUS_AVAILABLE, "I'm Available"}, + {YAHOO_STATUS_BRB, "Be Right Back"}, + {YAHOO_STATUS_BUSY, "Busy"}, + {YAHOO_STATUS_NOTATHOME, "Not at Home"}, + {YAHOO_STATUS_NOTATDESK, "Not at my Desk"}, + {YAHOO_STATUS_NOTINOFFICE, "Not in the Office"}, + {YAHOO_STATUS_ONPHONE, "On the Phone"}, + {YAHOO_STATUS_ONVACATION, "On Vacation"}, + {YAHOO_STATUS_OUTTOLUNCH, "Out to Lunch"}, + {YAHOO_STATUS_STEPPEDOUT, "Stepped Out"}, + {YAHOO_STATUS_INVISIBLE, "Invisible"}, + {YAHOO_STATUS_IDLE, "Idle"}, + {YAHOO_STATUS_CUSTOM, "Custom Message"}, + {0, NULL} +}; + +/* Status codes */ +static struct yahoo_idlabel yahoo_status_append[] = { + {YAHOO_STATUS_AVAILABLE, "is now available"}, + {YAHOO_STATUS_BRB, "will be right back"}, + {YAHOO_STATUS_BUSY, "is now busy"}, + {YAHOO_STATUS_NOTATHOME, "is not at home"}, + {YAHOO_STATUS_NOTATDESK, "is not at their desk"}, + {YAHOO_STATUS_NOTINOFFICE, "is not in the office"}, + {YAHOO_STATUS_ONPHONE, "is on the phone"}, + {YAHOO_STATUS_ONVACATION, "is on vacation"}, + {YAHOO_STATUS_OUTTOLUNCH, "is out to lunch"}, + {YAHOO_STATUS_STEPPEDOUT, "has stepped out"}, + {YAHOO_STATUS_INVISIBLE, "is now invisible"}, + {YAHOO_STATUS_IDLE, "is now idle"}, + {YAHOO_STATUS_CUSTOM, ""}, + {0, NULL} +}; + +/* Take a 4-byte character string in little-endian format and return + a unsigned integer */ +unsigned int yahoo_makeint(unsigned char *data) +{ + if (data) + { + return ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) + + (data[0])); + } + return 0; +} + +/* Take an integer and store it into a 4 character little-endian string */ +static void yahoo_storeint(unsigned char *data, unsigned int val) +{ + unsigned int tmp = val; + int i; + + if (data) + { + for (i = 0; i < 4; i++) + { + data[i] = tmp % 256; + tmp >>= 8; + } + } +} + +/* + converts a comma seperated list to an array of strings + used primarily in conference code + + allocates a string in here -- caller needs to free it + */ +char **yahoo_list2array(char *buff) +{ + char **tmp_array = NULL; + char *array_elem = NULL; + char *tmp = NULL; + + char *buffer = 0; + char *ptr_buffer = 0; + + int sublen = 0; + int cnt = 0; + int nxtelem = 0; + unsigned int i = 0; + unsigned int len = 0; + + if (0 == buff) + return 0; + + buffer = strdup(buff); /* play with a copy */ + ptr_buffer = buffer; + + /* count the number of users (commas + 1) */ + for (i = 0; i < strlen(buffer); i++) + { + if (buffer[i] == ',') + { + /* + if not looking at end of list + ( ignore extra pesky comma at end of list) + */ + if (i != (strlen(buffer) - 1)) + cnt++; + } + } + + /* add one more name than comma .. */ + cnt++; + + /* allocate the array to hold the list of buddys */ + /* null terminated array of pointers */ + tmp_array = (char **) malloc(sizeof(char *) * (cnt + 1)); + + memset(tmp_array, 0, (sizeof(char *) * (cnt + 1))); + + /* Parse through the list and get all the entries */ + while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0')) + sublen++; + tmp = (char *) malloc(sizeof(char) * (sublen + 1)); + + memcpy(tmp, ptr_buffer, sublen); + tmp[sublen] = '\0'; + + if (ptr_buffer[sublen] != '\0') + ptr_buffer = &(ptr_buffer[sublen + 1]); + else + ptr_buffer = &(ptr_buffer[sublen]); /* stay at the null char */ + sublen = 0; + + while (tmp && (strcmp(tmp, "") != 0)) + { + len = strlen(tmp); + array_elem = (char *) malloc(sizeof(char) * (len + 1)); + + strncpy(array_elem, tmp, (len + 1)); + array_elem[len] = '\0'; + + tmp_array[nxtelem++] = array_elem; + array_elem = NULL; + + FREE(tmp); + + while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0')) + sublen++; + tmp = (char *) malloc(sizeof(char) * (sublen + 1)); + + memcpy(tmp, ptr_buffer, sublen); + tmp[sublen] = '\0'; + + if (ptr_buffer[sublen] != '\0') + ptr_buffer = &(ptr_buffer[sublen + 1]); + else + ptr_buffer = &(ptr_buffer[sublen]); /* stay at the null char */ + + sublen = 0; + } + tmp_array[nxtelem] = NULL; + + FREE(tmp); + FREE(buffer); + return (tmp_array); + +} /* yahoo_list2array() */ + +/* + Free's the memory associated with an array generated bu yahoo_list2array + */ +void yahoo_arraykill(char **array) +{ + int nxtelem = 0; + + if (NULL == array) + return; + + while (array[nxtelem] != NULL) + { + free(array[nxtelem++]); + } + + free(array); +} /* yahoo_arraykill() */ + +/* + converts an array of strings to a comma seperated list + used primarily in conference code + + allocates a string in here.. needs to be freed by caller program + */ +char *yahoo_array2list(char **array) +{ + char *list = NULL; + int nxtelem = 0; + int arraylength = 0; + + if (NULL == array) + return NULL; + + while (array[nxtelem] != NULL) + { + arraylength += strlen(array[nxtelem++]); + arraylength++; /* comma */ + } + + nxtelem = 0; /* reset array counter */ + + /* allocate at least one - for NULL list - and to + allow my strcat to write past the end for the + last comma which gets converted to NULL */ + list = (char *) malloc(sizeof(char) * (arraylength + 1)); + + memset(list, 0, (arraylength + 1)); + + while (array[nxtelem] != NULL) + { + strcat(list, array[nxtelem++]); + strcat(list, ","); + } + /* + overwrite last ',' with a NULL + makes the string end with two null characters, but this way + handles empty lists gracefully + */ + list[arraylength - 1] = '\0'; + + return (list); +} /* yahoo_array2list() */ + +/* Free a buddy list */ +static void yahoo_free_buddies(struct yahoo_context *ctx) +{ + int i; + + if (!ctx->buddies) + { + return; + } + + i = 0; + while (ctx->buddies[i]) + { + FREE(ctx->buddies[i]->group); + FREE(ctx->buddies[i]->id); + i++; + } + + FREE(ctx->buddies); +} + +/* Free a identities list */ +static void yahoo_free_identities(struct yahoo_context *ctx) +{ + int i; + + if (!ctx->identities) + { + return; + } + + i = 0; + while (ctx->identities[i]) + { + FREE(ctx->identities[i]); + i++; + } + + FREE(ctx->identities); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_free_identities: done\n"); +} + +#if 0 /* not used at the moment */ +static void yahoo_hexdump(char *label, unsigned char *data, int datalen) +{ + int i, j; + int val, skipped_last; + char current[100]; + char last[100]; + char tmp[15]; + char outline[100]; + static int last_datalen = 0; + static unsigned char *last_data = NULL; + + if (last_data) + { + if (last_datalen == datalen && !memcmp(data, last_data, datalen)) + { + printf("\n%s: <same as last dump>\n", label); + return; + } + FREE(last_data); + } + + /* Copy the packet so we can don't duplicate it next time. */ + last_datalen = datalen; + last_data = (unsigned char *) malloc(datalen); + memcpy(last_data, data, datalen); + + /* Handle printing the full entry out */ + printf("\n"); + printf("%s:\n", label); + + skipped_last = 0; + last[0] = 0; + for (j = 0; j * 16 < datalen; j++) + { + current[0] = 0; + + /* Print out in hex */ + for (i = j * 16; i < (j * 16 + 16); i++) + { + if (i < datalen) + { + val = data[i]; + sprintf(tmp, "%.2X ", val); + } + else + { + sprintf(tmp, " "); + } + strcat(current, tmp); + } + + /* Print out in ascii */ + strcat(current, " "); + for (i = j * 16; i < (j * 16) + 16; i++) + { + if (i < datalen) + { + if (isprint(data[i])) + { + sprintf(tmp, "%c", data[i]); + } + else + { + sprintf(tmp, "."); + } + } + else + { + sprintf(tmp, " "); + } + strcat(current, tmp); + } + + outline[0] = 0; + if (!strcmp(current, last)) + { + if (!skipped_last) + { + strcpy(outline, " ....:\n"); + } + skipped_last = 1; + } + else + { + sprintf(outline, " %.4d: %s\n", j * 16, current); + skipped_last = 0; + } + printf("%s", outline); + strcpy(last, current); + } + + if (skipped_last) + { + printf("%s", outline); + } + printf("\n"); +} +#endif + +static int yahoo_socket_connect(struct yahoo_context *ctx, char *host, + int port) +{ + struct sockaddr_in serv_addr; + struct hostent *server; + int servfd; + int res; + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_socket_connect - starting [%s:%d]\n", host, port); + + if (!ctx || !host || !port) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_socket_connect - nulls\n"); + return 0; + } + + server = gethostbyname(host); + if (!server) + { + printf("[libyahoo] failed to look up server (%s:%d)\n", host, port); + return (0); + } + + servfd = socket(AF_INET, SOCK_STREAM, 0); + + bzero(&serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length); + serv_addr.sin_port = htons(port); + + res = -1; + if (ctx->connect_mode == YAHOO_CONNECT_SOCKS4) + { +#if defined(WITH_SOCKS4) + res = + Rconnect(servfd, (struct sockaddr *) &serv_addr, + sizeof(serv_addr)); +#endif + } + else if (ctx->connect_mode == YAHOO_CONNECT_SOCKS5) + { +#if defined(WITH_SOCKS5) +#endif + } + else if (ctx->connect_mode == YAHOO_CONNECT_NORMAL || + ctx->connect_mode == YAHOO_CONNECT_HTTP || + ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + res = + connect(servfd, (struct sockaddr *) &serv_addr, + sizeof(serv_addr)); + } + else + { + printf("[libyahoo] unhandled connect mode (%d).\n", + ctx->connect_mode); + return (0); + } + + if (res < 0) + { + close(servfd); + servfd = 0; + printf("[libyahoo] failed to connect to server (%s:%d)\n", host, + port); + return (0); + } + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_socket_connect - finished\n"); + return servfd; +} + +/* really ugly brute force approach - someone find a GPL'd/free + equivalent and replace this p.o.s. */ +static char *yahoo_urlencode(char *data) +{ + static char *tmp = NULL; + char buf[4]; + int i, len; + + len = 3 * strlen(data) + 1; + + FREE(tmp); + + if (!data) + { + return NULL; + } + + /* change this at some point to re-use the buffer, no sense + allocating repeatedly */ + tmp = (char *) malloc(len); + tmp[0] = 0; + + for (i = 0; i < strlen(data); i++) + { + if (isdigit((int) (data[i])) || + isalpha((int) data[i]) || data[i] == '_') + { + buf[0] = data[i]; + buf[1] = 0; + strcat(tmp, buf); + } + else + { + sprintf(buf, "%%%.2X", data[i]); + strcat(tmp, buf); + } + } + + return tmp; +} + +static void yahoo_addtobuffer(struct yahoo_context *ctx, char *data, + int datalen) +{ + //yahoo_hexdump("yahoo_addtobuffer", data, datalen); + + /* Check buffer, increase size if necessary */ + if (!ctx->io_buf + || ((ctx->io_buf_maxlen - ctx->io_buf_curlen) < (datalen + 100))) + { + char *new_io_buf; + + if (datalen < 10240) + { + ctx->io_buf_maxlen += 10240; + } + else + { + ctx->io_buf_maxlen += datalen; + } + new_io_buf = (char *) malloc(ctx->io_buf_maxlen); + + if (ctx->io_buf) + { + memcpy(new_io_buf, ctx->io_buf, ctx->io_buf_curlen); + FREE(ctx->io_buf); + } + + ctx->io_buf = new_io_buf; + } + + memcpy(ctx->io_buf + ctx->io_buf_curlen, data, datalen); + ctx->io_buf_curlen += datalen; +} + +static int yahoo_tcp_readline(char *ptr, int maxlen, int fd) +{ + int n, rc; + char c; + + for (n = 1; n < maxlen; n++) + { + again: + + if ((rc = read(fd, &c, 1)) == 1) + { + *ptr++ = c; + if (c == '\n') + break; + } + else if (rc == 0) + { + if (n == 1) + return (0); /* EOF, no data */ + else + break; /* EOF, w/ data */ + } + else + { + if (errno == EINTR) + goto again; + printf + ("Yahoo: Error reading from socket in yahoo_tcp_readline.\n"); + exit(1); + } + } + + *ptr = 0; + return (n); +} + +/* + * Published library interfaces + */ + +/* Initialize interface to yahoo library, sortof like a class object + creation routine. */ +struct yahoo_context *yahoo_init(char *user, char *password, + struct yahoo_options *options) +{ + struct yahoo_context *tmp; + + if (!user || !password) + { + return NULL; + } + + /* Allocate a new context */ + tmp = (struct yahoo_context *) calloc(1, sizeof(*tmp)); + + /* Fill in any available info */ + tmp->user = strdup(user); + tmp->password = strdup(password); + if (options->proxy_host) + { + tmp->proxy_host = strdup(options->proxy_host); + } + tmp->proxy_port = options->proxy_port; + tmp->connect_mode = options->connect_mode; + +#if defined(WITH_SOCKS4) + if (connect_mode == YAHOO_CONNECT_SOCKS4) + { + static int did_socks_init = 0; + + if (did_socks_init == 0) + { + SOCKSinit("libyahoo"); + did_socks_init = 1; + } + } +#endif + + /* Fetch the cookies */ + if (!yahoo_fetchcookies(tmp)) + { + yahoo_free_context(tmp); + return NULL; + } + + return tmp; +} + +/* Free a yahoo context */ +void yahoo_free_context(struct yahoo_context *ctx) +{ + FREE(ctx->user); + FREE(ctx->password); + FREE(ctx->proxy_host); + FREE(ctx->io_buf); + FREE(ctx->cookie); + FREE(ctx->login_cookie); + FREE(ctx->login_id); + + yahoo_free_buddies(ctx); + yahoo_free_identities(ctx); + + FREE(ctx); +} + +/* Turn a status code into it's corresponding string */ +char *yahoo_get_status_string(int statuscode) +{ + int i; + + for (i = 0; yahoo_status_codes[i].label; i++) + { + if (yahoo_status_codes[i].id == statuscode) + { + return yahoo_status_codes[i].label; + } + } + return NULL; +} + +/* Turn a status code into it's corresponding string */ +char *yahoo_get_status_append(int statuscode) +{ + int i; + + for (i = 0; yahoo_status_append[i].label; i++) + { + if (yahoo_status_append[i].id == statuscode) + { + return yahoo_status_append[i].label; + } + } + return NULL; +} + +/* Turn a service code into it's corresponding string */ +char *yahoo_get_service_string(int servicecode) +{ + int i; + char *name = "Unknown Service"; + static char tmp[50]; + + for (i = 0; yahoo_service_codes[i].label; i++) + { + if (yahoo_service_codes[i].id == servicecode) + { + name = yahoo_service_codes[i].label; + break; + } + } + + snprintf(tmp, 50, "(%d) %s", servicecode, name); + return tmp; +} + +/* Return a malloc()'d copy of the users cookie */ +int yahoo_fetchcookies(struct yahoo_context *ctx) +{ + char buffer[5000]; + int servfd; + int i; + int res; + char *tmpstr; + + if (!ctx) + { + return 0; + } + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_fetchcookies: starting\n"); + + /* Check for cached cookie */ + if (ctx->cookie) + { + FREE(ctx->cookie); + } + if (ctx->login_cookie) + { + FREE(ctx->login_cookie); + } + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + servfd = yahoo_socket_connect(ctx, YAHOO_AUTH_HOST, YAHOO_AUTH_PORT); + } + if (!servfd) + { + printf("[libyahoo] failed to connect to pager auth server.\n"); + return (0); + } + + strcpy(buffer, "GET "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, "http://" YAHOO_AUTH_HOST); + } + strcat(buffer, "/config/ncclogin?login="); + if (ctx->login_id) + { + strcat(buffer, yahoo_urlencode(ctx->login_id)); + } + else + { + strcat(buffer, yahoo_urlencode(ctx->user)); + } + strcat(buffer, "&passwd="); + strcat(buffer, yahoo_urlencode(ctx->password)); + strcat(buffer, "&n=1 HTTP/1.0\r\n"); + strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n"); + strcat(buffer, "Host: " YAHOO_AUTH_HOST "\r\n"); + strcat(buffer, "\r\n"); + + write(servfd, buffer, strlen(buffer)); + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: writing buffer '%s'\n", buffer); + + ctx->cookie = NULL; + while ((res = yahoo_tcp_readline(buffer, 5000, servfd)) > 0) + { + /* strip out any non-alphas */ + for (i = 0; i < strlen(buffer); i++) + { + if (!isprint((int) buffer[i])) + { + buffer[i] = 0; + } + } + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: read buffer '%s'\n", buffer); + + if (!strcasecmp(buffer, "ERROR: Invalid NCC Login")) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: password was invalid\n"); + return (0); + } + + if (!strncasecmp(buffer, "Set-Cookie: Y=", 14)) + { + FREE(ctx->cookie); + ctx->cookie = strdup(buffer + 12); + + tmpstr = strchr(ctx->cookie, ';'); + if (tmpstr) + { + *tmpstr = '\0'; + } + } + } + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: closing server connection\n"); + close(servfd); + servfd = 0; + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: closed server connection\n"); + + if (ctx->cookie) + { + tmpstr = strstr(ctx->cookie, "n="); + if (tmpstr) + { + ctx->login_cookie = strdup(tmpstr + 2); + } + + tmpstr = strchr(ctx->login_cookie, '&'); + if (tmpstr) + { + *tmpstr = '\0'; + } + } + + if (ctx->cookie) + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: cookie (%s)\n", ctx->cookie); + if (ctx->login_cookie) + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_fetchcookies: login cookie (%s)\n", + ctx->login_cookie); + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_fetchcookies: done\n"); + + return 1; +} + +/* Add a buddy to your buddy list */ +int yahoo_add_buddy(struct yahoo_context *ctx, char *addid, + char *active_id, char *group, char *msg) +{ + char buffer[5000]; + int servfd; + + if (!ctx) + { + return 0; + } + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_add_buddy - connecting via proxy\n"); + servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_add_buddy - connecting\n"); + servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT); + } + if (!servfd) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_add_buddy: failed to connect\n"); + return (0); + } + + strcpy(buffer, "GET "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, "http://" YAHOO_DATA_HOST); + } + strcat(buffer, "/config/set_buddygrp?.bg="); + strcat(buffer, yahoo_urlencode(group)); + strcat(buffer, "&.src=bl&.cmd=a&.bdl="); + strcat(buffer, yahoo_urlencode(addid)); + strcat(buffer, "&.id="); + strcat(buffer, yahoo_urlencode(active_id)); + strcat(buffer, "&.l="); + strcat(buffer, yahoo_urlencode(ctx->user)); + strcat(buffer, "&.amsg="); + strcat(buffer, yahoo_urlencode(msg)); + strcat(buffer, " HTTP/1.0\r\n"); + + strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n"); + strcat(buffer, "Host: " YAHOO_DATA_HOST "\r\n"); + strcat(buffer, "Cookie: "); + strcat(buffer, ctx->cookie); + strcat(buffer, "\r\n"); + strcat(buffer, "\r\n"); + + write(servfd, buffer, strlen(buffer)); + while (yahoo_tcp_readline(buffer, 5000, servfd) > 0) + { + /* just dump the output, I don't care about errors at the moment */ + } + close(servfd); + servfd = 0; + + /* indicate success for now with 0 */ + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy: finished\n"); + return 0; +} + +/* Remove a buddy from your buddy list */ +int yahoo_remove_buddy(struct yahoo_context *ctx, char *addid, + char *active_id, char *group, char *msg) +{ + char buffer[5000]; + int servfd; + + if (!ctx) + { + return 0; + } + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_add_buddy - connecting via proxy\n"); + servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy - connecting\n"); + servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT); + } + if (!servfd) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_add_buddy: failed to connect\n"); + return (0); + } + + strcpy(buffer, "GET "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, "http://" YAHOO_DATA_HOST); + } + strcat(buffer, "/config/set_buddygrp?.bg="); + strcat(buffer, yahoo_urlencode(group)); + strcat(buffer, "&.src=bl&.cmd=d&.bdl="); + strcat(buffer, yahoo_urlencode(addid)); + strcat(buffer, "&.id="); + strcat(buffer, yahoo_urlencode(active_id)); + strcat(buffer, "&.l="); + strcat(buffer, yahoo_urlencode(ctx->user)); + strcat(buffer, "&.amsg="); + strcat(buffer, yahoo_urlencode(msg)); + strcat(buffer, " HTTP/1.0\r\n"); + + strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n"); + strcat(buffer, "Host: " YAHOO_DATA_HOST "\r\n"); + strcat(buffer, "Cookie: "); + strcat(buffer, ctx->cookie); + strcat(buffer, "\r\n"); + strcat(buffer, "\r\n"); + + write(servfd, buffer, strlen(buffer)); + while (yahoo_tcp_readline(buffer, 5000, servfd) > 0) + { + /* just dump the output, I don't care about errors at the moment */ + } + close(servfd); + servfd = 0; + + /* indicate success for now with 0 */ + return 0; +} + +/* Retrieve the configuration from the server */ +int yahoo_get_config(struct yahoo_context *ctx) +{ + char buffer[5000]; + int i, j; + int servfd; + int commas; + int in_section; + struct yahoo_buddy **buddylist = NULL; + int buddycnt = 0; + int nextbuddy = 0; + + /* Check for cached cookie */ + if (!ctx || !ctx->cookie) + { + return 0; + } + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config: starting\n"); + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT); + } + if (!servfd) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: failed to connect\n"); + return (0); + } + + strcpy(buffer, "GET "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, "http://" YAHOO_DATA_HOST); + } + strcat(buffer, "/config/get_buddylist?.src=bl HTTP/1.0\r\n"); + strcat(buffer, "Cookie: "); + strcat(buffer, ctx->cookie); + strcat(buffer, "\r\n"); + strcat(buffer, "\r\n"); + + write(servfd, buffer, strlen(buffer)); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config: sending '%s'\n", + buffer); + + in_section = 0; + while (yahoo_tcp_readline(buffer, 5000, servfd) > 0) + { + /* strip out any non-alphas */ + for (i = 0; i < strlen(buffer); i++) + { + if (!isprint((int) buffer[i])) + { + for (j = i; j < strlen(buffer); j++) + { + buffer[j] = buffer[j + 1]; + } + } + } + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: read '%s'\n", buffer); + + if (!strcasecmp(buffer, "BEGIN IDENTITIES")) + { + in_section = 1; + } + else if (!strcasecmp(buffer, "END IDENTITIES")) + { + in_section = 0; + } + else if (!strcasecmp(buffer, "BEGIN BUDDYLIST")) + { + in_section = 2; + } + else if (!strcasecmp(buffer, "END BUDDYLIST")) + { + in_section = 0; + } + else if (in_section == 1) + { + char *tmp; + + /* count the commas */ + commas = 0; + for (i = 0; i < strlen(buffer); i++) + { + if (buffer[i] == ',') + { + commas++; + } + } + + /* make sure we've gotten rid of any previous identities array */ + yahoo_free_identities(ctx); + + /* allocate the array to hold the list of identities */ + ctx->identities = (char **) calloc(commas + 2, sizeof(char *)); + + /* Parse through the list and get all the entries */ + i = 0; + tmp = strtok(buffer, ","); + while (tmp) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: retrieved " + "identity '%s'\n", tmp); + ctx->identities[i++] = strdup(tmp); + tmp = strtok(NULL, ","); + } + ctx->identities[i] = 0; + } + else if (in_section == 2) + { + char *group; + char *tmp; + struct yahoo_buddy **tmp_buddylist; + struct yahoo_buddy *tmpbuddy; + int tmp_buddycnt; + + /* count the buddies on this line */ + tmp_buddycnt = buddycnt; + for (i = 0; i < strlen(buffer); i++) + { + if (buffer[i] == ',') + { + buddycnt++; + } + } + buddycnt++; /* always one more than comma count */ + + /* allocate the array to hold the list of buddy */ + tmp_buddylist = (struct yahoo_buddy **) + malloc(sizeof(struct yahoo_buddy *) * (buddycnt + 1)); + + /* Free and copy the old one if necessary */ + if (buddylist) + { + memcpy(tmp_buddylist, buddylist, + + (tmp_buddycnt + 1) * sizeof(struct yahoo_buddy *)); + + FREE(buddylist); + } + buddylist = tmp_buddylist; + + /* Parse through the list and get all the entries */ + tmp = strtok(buffer, ",:"); + group = NULL; + while (tmp) + { + if (tmp == buffer) /* group name */ + { + group = tmp; + } + else + { + tmpbuddy = (struct yahoo_buddy *) + + malloc(sizeof(struct yahoo_buddy)); + + tmpbuddy->id = strdup(tmp); + tmpbuddy->group = strdup(group); + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: retrieved buddy '%s:%s'\n", + group, tmp); + buddylist[nextbuddy++] = tmpbuddy; + } + tmp = strtok(NULL, ","); + } + buddylist[nextbuddy] = 0; + } + else if (!strncasecmp(buffer, "Mail=", strlen("Mail="))) + { + ctx->mail = atoi(buffer + strlen("Mail=")); + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: retrieved mail flag '%d'\n", + ctx->mail); + } + else if (!strncasecmp(buffer, "Login=", strlen("Login="))) + { + FREE(ctx->login_id); + ctx->login_id = strdup(buffer + strlen("Login=")); + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config: retrieved login id '%s'\n", + ctx->login_id); + } + } + close(servfd); + servfd = 0; + + yahoo_free_buddies(ctx); + ctx->buddies = buddylist; + + /* fill in a bogus login_in, just in case */ + if (!ctx->login_id) + { + ctx->login_id = strdup(ctx->user); + } + + /* refetch the cookie if the login_id is different so that + it will have the correct info in it */ + if (strcmp(ctx->login_id, ctx->user)) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_get_config - refetching cookies\n"); + yahoo_fetchcookies(ctx); + } + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config - finished\n"); + + return 1; +} + +/* Log in, optionally activating other secondary identities */ +int yahoo_cmd_logon(struct yahoo_context *ctx, unsigned int initial_status) +{ + char login_string[5000]; /* need to change to malloc ASAP */ + char *tmpid; + char **identities = ctx->identities; + int i; + + if (!ctx || !ctx->login_cookie) + { + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_cmd_logon: logon called without " + "context and/or cookie.\n"); + exit(1); + } + + strcpy(login_string, ctx->login_cookie); +/* testing with new logon code */ +// strcpy(login_string, "$1$_2S43d5f$XXXXXXXXWtRKNclLWyy8C."); + + login_string[strlen(login_string) + 1] = 0; + login_string[strlen(login_string)] = 1; /* control-A */ + + strcat(login_string, ctx->user); + + /* Send all identities */ + if (identities) + { + i = 0; + tmpid = identities[i]; + while (tmpid) + { + if (strcasecmp(tmpid, ctx->user)) + { + strcat(login_string, ","); + strcat(login_string, tmpid); + } + tmpid = identities[i++]; + } + } + + yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGON, ctx->user, login_string, + initial_status); + + /* something that the windows one sends, not sure what it is */ +#if 0 + login_string[0] = 0; + strcat(login_string, "C=0\002"); + strcat(login_string, "F=0,P=0,H=0,S=0,W=0,O=0\002"); + strcat(login_string, "M=0,P=0,C=0,S=0"); + yahoo_sendcmd(ctx, YAHOO_SERVICE_PASSTHROUGH2, ctx->user, login_string, + 0); +#endif + + return 0; +} + +int yahoo_connect(struct yahoo_context *ctx) +{ + int res; + + res = 0; + ctx->sockfd = 0; + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_connect - starting\n"); + + switch (ctx->connect_mode) + { + case YAHOO_CONNECT_SOCKS4: + case YAHOO_CONNECT_SOCKS5: + case YAHOO_CONNECT_NORMAL: + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_connect - establishing socket connection\n"); + ctx->sockfd = + yahoo_socket_connect(ctx, YAHOO_PAGER_HOST, YAHOO_PAGER_PORT); + if (!ctx->sockfd) + { + printf("[libyahoo] couldn't connect to pager host\n"); + return (0); + } + break; + + case YAHOO_CONNECT_HTTP: + case YAHOO_CONNECT_HTTPPROXY: + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_connect - no connect for HTTP\n"); + /* no pager connection will be established for this */ + break; + + default: + printf("[libyahoo] unhandled connect mode (%d)\n", + ctx->connect_mode); + } + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_connect - finished\n"); + return (1); +} + +/* Send a packet to the server via http connection method */ +/* at moment only handles regular http connection, once I have that + working, this code needs to also do http proxy connections as well */ +int yahoo_sendcmd_http(struct yahoo_context *ctx, struct yahoo_rawpacket *pkt) +{ + int sockfd; + char buffer[5000]; + char tmpbuf[1000]; + int size; + int res; + + if (!ctx || !pkt) + { + return (0); + } + + size = YAHOO_PACKET_HEADER_SIZE + strlen(pkt->content) + 1; + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + sockfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + sockfd = yahoo_socket_connect(ctx, YAHOO_PAGER_HTTP_HOST, + YAHOO_PAGER_HTTP_PORT); + } + if (!sockfd) + { + printf("[libyahoo] failed to connect to pager http server.\n"); + return (0); + } + + strcpy(buffer, "POST "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, "http://" YAHOO_PAGER_HTTP_HOST); + } + strcat(buffer, "/notify HTTP/1.0\r\n"); + + strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n"); + strcat(buffer, "Host: " YAHOO_PAGER_HTTP_HOST "\r\n"); + snprintf(tmpbuf, 1000, "Content-Length: %d\r\n", size); + strcat(buffer, tmpbuf); + + strcat(buffer, "Pragma: No-Cache\r\n"); + + strcat(buffer, "Cookie: "); + strcat(buffer, ctx->cookie); + strcat(buffer, "\r\n"); + strcat(buffer, "\r\n"); + + write(sockfd, buffer, strlen(buffer)); + write(sockfd, pkt, size); + write(sockfd, "\r\n", 2); + + /* now we need to read the results */ + /* I'm taking the cheat approach and just dumping them onto the + buffer, headers and all, the _skip_to_YHOO_ code will handle it + for now */ + + while ((res = read(sockfd, buffer, 5000)) > 0) + { + if (res == -1) + { + printf("[libyahoo] Error reading data from server.\n"); + exit(1); + } + yahoo_addtobuffer(ctx, buffer, res); + } + close(sockfd); + sockfd = 0; + + return (0); +} + +/* Send a packet to the server, called by all routines that want to issue + a command. */ +int yahoo_sendcmd(struct yahoo_context *ctx, int service, char *active_nick, + char *content, unsigned int msgtype) +{ + int size; + struct yahoo_rawpacket *pkt; + int maxcontentsize; + + /* why the )&*@#$( did they hardwire the packet size that gets sent + when the size of the packet is included in what is sent, bizarre */ + size = 4 * 256 + YAHOO_PACKET_HEADER_SIZE; + pkt = (struct yahoo_rawpacket *) calloc(1, size); + + /* figure out max content length, including trailing null */ + maxcontentsize = size - sizeof(struct yahoo_rawpacket); + + /* Build the packet */ + strcpy(pkt->version, YAHOO_PROTOCOL_HEADER); + yahoo_storeint(pkt->len, size); + yahoo_storeint(pkt->service, service); + + /* not sure if this is valid with YPNS1.4 or if it needs 2.0 */ + yahoo_storeint(pkt->msgtype, msgtype); + + /* Not sure, but might as well send for regular connections as well. */ + yahoo_storeint(pkt->magic_id, ctx->magic_id); + strcpy(pkt->nick1, ctx->login_id); + strcpy(pkt->nick2, active_nick); + strncpy(pkt->content, content, maxcontentsize); + + // yahoo_hexdump("send_cmd", (char *) pkt, size); + + switch (ctx->connect_mode) + { + case YAHOO_CONNECT_SOCKS4: + case YAHOO_CONNECT_SOCKS5: + case YAHOO_CONNECT_NORMAL: + write(ctx->sockfd, pkt, size); + break; + case YAHOO_CONNECT_HTTP: + case YAHOO_CONNECT_HTTPPROXY: + yahoo_sendcmd_http(ctx, pkt); + break; + } + + FREE(pkt); + return (0); +} + +int yahoo_cmd_ping(struct yahoo_context *ctx) +{ + yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0); + return (0); +} + +int yahoo_cmd_idle(struct yahoo_context *ctx) +{ + yahoo_sendcmd(ctx, YAHOO_SERVICE_IDLE, ctx->user, "", 0); + return (0); +} + +int yahoo_cmd_sendfile(struct yahoo_context *ctx, char *active_user, + char *touser, char *msg, char *filename) +{ + yahoo_dbg_Print("libyahoo", "yahoo_cmd_sendfile not implemented yet!"); + return (0); +} + +int yahoo_cmd_msg(struct yahoo_context *ctx, char *active_user, + char *touser, char *msg) +{ + char *content; + + content = (char *) malloc(strlen(touser) + strlen(msg) + 5); + + if (strlen(touser)) + { + sprintf(content, "%s,%s", touser, msg); + yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content, 0); + } + + FREE(content); + return (0); +} + +int yahoo_cmd_msg_offline(struct yahoo_context *ctx, char *active_user, + char *touser, char *msg) +{ + char *content; + + content = (char *) malloc(strlen(touser) + strlen(msg) + 5); + + if (strlen(touser)) + { + sprintf(content, "%s,%s", touser, msg); + yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content, + YAHOO_MSGTYPE_KNOWN_USER); + } + + FREE(content); + return (0); +} + +/* appended the " " so that won't trigger yahoo bug - hack for the moment */ +int yahoo_cmd_set_away_mode(struct yahoo_context *ctx, int status, char *msg) +{ + char statusstring[500]; + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_cmd_set_away_mode: set status (%d), msg(%s)\n", + status, yahoo_dbg_NullCheck(msg)); + + if (status == YAHOO_STATUS_CUSTOM) + { + if (msg && msg[0] != 0) + { + snprintf(statusstring, 500, "%d%c%s", status, 1, msg); + } + else + { + snprintf(statusstring, 500, "%d%c---", status, 1); + } + } + else + { + snprintf(statusstring, 500, "%d", status); + } + yahoo_sendcmd(ctx, YAHOO_SERVICE_ISAWAY, ctx->user, statusstring, 0); + + return 0; +} + +int yahoo_cmd_set_back_mode(struct yahoo_context *ctx, int status, char *msg) +{ + char statusstring[500]; + + yahoo_dbg_Print("libyahoo", + "[libyahoo] yahoo_cmd_set_back_mode: set status (%d), msg(%s)\n", + status, yahoo_dbg_NullCheck(msg)); + + snprintf(statusstring, 500, "%d%c%s ", status, 1, msg ? msg : ""); + yahoo_sendcmd(ctx, YAHOO_SERVICE_ISBACK, ctx->user, statusstring, 0); + + return 0; +} + +int yahoo_cmd_activate_id(struct yahoo_context *ctx, char *newid) +{ + if (strlen(newid)) + { + yahoo_sendcmd(ctx, YAHOO_SERVICE_IDACT, newid, newid, 0); + } + return (0); +} + +int yahoo_cmd_user_status(struct yahoo_context *ctx) +{ + yahoo_sendcmd(ctx, YAHOO_SERVICE_USERSTAT, ctx->user, "", 0); + return (0); +} + +int yahoo_cmd_logoff(struct yahoo_context *ctx) +{ + yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGOFF, ctx->user, ctx->user, 0); + return (0); +} + +/* + +yahoo_cmd_start_conf() + + Starts a conference. (You create the conference) + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + You create this id to start the conference, but pass it + along after that. + char **userlist == Users to invite. Null terminated array of strings. + car *msg == Invitiation message. + int type == 0 - normal, 1 - voice (not supported yet) + +Packet format: + id^invited-users^msg^0or1 +*/ +int yahoo_cmd_start_conf(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *msg, int type) +{ + char ctrlb = 2; + char *content; + char *new_userlist = yahoo_array2list(userlist); + int cont_len = 0; + +#ifdef ENABLE_LIBYAHOO_DEBUG + char *unraw_msg = NULL; +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + + int size = strlen(conf_id) + strlen(msg) + 8 + strlen(new_userlist); + + content = (char *) malloc(size); + memset(content, 0, size); + + cont_len = snprintf(content, + size - 1, + "%s%c%s%c%s%c%d", + conf_id, ctrlb, new_userlist, ctrlb, msg, ctrlb, type); + +#ifdef ENABLE_LIBYAHOO_DEBUG + unraw_msg = yahoo_unraw_buffer(content, cont_len); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_start_conf: %s\n", + unraw_msg); + free(unraw_msg); +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFINVITE, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* +yahoo_cmd_conf_logon() + + Reply to a conference invitation, logs you into conference. + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + This comes from the invitiation. + char *host == The person that sent you the invitation. + char **userlist == Everyone else invited. This comes from the invitiation. + Null terminated array of strings. + +Packet format: + id^all-invited-users-and-host + +*/ +int yahoo_cmd_conf_logon(struct yahoo_context *ctx, char *conf_id, + char *host, char **userlist) +{ + char ctrlb = 2; + char *content; + char *new_userlist = yahoo_array2list(userlist); + int cont_len = 0; + +#ifdef ENABLE_LIBYAHOO_DEBUG + char *unraw_msg = NULL; +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + + int size = strlen(conf_id) + strlen(host) + 8 + strlen(new_userlist); + + content = (char *) malloc(size); + memset(content, 0, size); + + cont_len = + sprintf(content, "%s%c%s,%s", conf_id, ctrlb, host, new_userlist); + +#ifdef ENABLE_LIBYAHOO_DEBUG + unraw_msg = yahoo_unraw_buffer(content, cont_len); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logon: %s\n", + unraw_msg); + free(unraw_msg); +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGON, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* + +yahoo_cmd_decline_conf() + + Reply to a conference invitation, decline offer. + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + This comes from the invitiation. + char *host == The person that sent you the invitation. + char **userlist == Everyone else invited. This comes from the invitiation. + Null terminated array of strings. + (Null if replying to a conference additional invite ) + char *msg == Reason for declining. + +Packet format: + id^all-invited-users-and-host^msg + +*/ +int yahoo_cmd_decline_conf(struct yahoo_context *ctx, char *conf_id, + char *host, char **userlist, char *msg) +{ + char ctrlb = 2; + char *content; + char *new_userlist = yahoo_array2list(userlist); + + int size = + + strlen(conf_id) + strlen(host) + strlen(msg) + 8 + + strlen(new_userlist); + + content = (char *) malloc(size); + memset(content, 0, size); + + sprintf(content, "%s%c%s,%s%c%s", conf_id, ctrlb, host, new_userlist, + ctrlb, msg); + + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_decline_conf: %s\n", + content); + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFDECLINE, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* + +yahoo_cmd_conf_logoff() + + Logoff of a conference. + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + This comes from the invitiation. + char **userlist == Everyone in conference. + Null terminated array of strings. + +Packet format: + id^all-invited-users + +*/ + +int yahoo_cmd_conf_logoff(struct yahoo_context *ctx, char *conf_id, + char **userlist) +{ + char ctrlb = 2; + char *content; + int cont_len = 0; + +#ifdef ENABLE_LIBYAHOO_DEBUG + char *unraw_msg = NULL; +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + char *new_userlist = yahoo_array2list(userlist); + + int size = strlen(conf_id) + strlen(new_userlist) + 8; + + content = (char *) malloc(size); + memset(content, 0, size); + + cont_len = + snprintf(content, size, "%s%c%s", conf_id, ctrlb, new_userlist); +#ifdef ENABLE_LIBYAHOO_DEBUG + unraw_msg = yahoo_unraw_buffer(content, cont_len); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logoff: %s\n", + unraw_msg); + free(unraw_msg); +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGOFF, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* + +yahoo_cmd_conf_invite() + + Invite another user to an already running conference. + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + This comes from the invitiation. + char *invited_user == The person being invited to conference. + char **userlist == Everyone else in conference. + Null terminated array of strings. + char *msg == Invitation message. + +Packet format: + id^invited-user^who-else-in-conf^who-else-in-conf^msg^0 + +*/ + +int yahoo_cmd_conf_invite(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *invited_user, char *msg) +{ + char ctrlb = 2; + char *content; + char *new_userlist = yahoo_array2list(userlist); + + int size = strlen(conf_id) + strlen(invited_user) + + (2 * strlen(new_userlist)) + strlen(msg) + 7; + + content = (char *) malloc(size); + memset(content, 0, size); + + sprintf(content, "%s%c%s%c%s%c%s%c%s%c0", conf_id, ctrlb, + invited_user, ctrlb, new_userlist, ctrlb, + new_userlist, ctrlb, msg, ctrlb); + yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_invite: %s\n", + content); + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFADDINVITE, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* + +yahoo_cmd_conf_msg() + + Send a message to everyone in conference. + +Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + This comes from the invitiation. + char **userlist == Everyone in conference. + Null terminated array of strings. + char *msg == Message to send. + +Packet format: + id^all-invited-users^msg + +*/ +int yahoo_cmd_conf_msg(struct yahoo_context *ctx, char *conf_id, + char **userlist, char *msg) +{ + char ctrlb = 2; + char *content; + int cont_len = 0; + +#ifdef ENABLE_LIBYAHOO_DEBUG + char *unraw_msg = NULL; +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + char *new_userlist = yahoo_array2list(userlist); + + int size = strlen(conf_id) + strlen(new_userlist) + strlen(msg) + 8; + + content = (char *) malloc(size); + memset(content, 0, size); + + cont_len = + snprintf(content, size, "%s%c%s%c%s", conf_id, ctrlb, new_userlist, + ctrlb, msg); +#ifdef ENABLE_LIBYAHOO_DEBUG + unraw_msg = yahoo_unraw_buffer(content, cont_len); + yahoo_dbg_Print("libyahoo", "yahoo_cmd_conf_msg: %s\n", unraw_msg); + free(unraw_msg); +#endif /* def ENABLE_LIBYAHOO_DEBUG */ + yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFMSG, ctx->user, content, 0); + + FREE(new_userlist); + FREE(content); + return (0); +} + +/* + * Free the rawpacket structure - primarily a placeholder + * since all static elements at the moment + */ +void yahoo_free_rawpacket(struct yahoo_rawpacket *pkt) +{ + FREE(pkt); +} + +/* + * Free entire packet structure including string elements + */ +void yahoo_free_packet(struct yahoo_packet *pkt) +{ + int i; + + if (pkt) + { + FREE(pkt->real_id); + FREE(pkt->active_id); + FREE(pkt->conf_id); + FREE(pkt->conf_host); + FREE(pkt->conf_user); + FREE(pkt->conf_msg); + FREE(pkt->cal_url); + FREE(pkt->cal_timestamp); + FREE(pkt->cal_title); + FREE(pkt->cal_description); + FREE(pkt->chat_invite_content); + FREE(pkt->msg_id); + FREE(pkt->msg_timestamp); + FREE(pkt->msg); + FREE(pkt->file_from); + FREE(pkt->file_flag); + FREE(pkt->file_url); + FREE(pkt->file_description); + FREE(pkt->group_old); + FREE(pkt->group_new); + if (pkt->idstatus) + { + for (i = 0; i < pkt->idstatus_count; i++) + { + yahoo_free_idstatus(pkt->idstatus[i]); + } + free(pkt->idstatus); + } + free(pkt); + } +} + +void yahoo_free_idstatus(struct yahoo_idstatus *idstatus) +{ + if (!idstatus) + { + return; + } + + FREE(idstatus->id); + FREE(idstatus->connection_id); + FREE(idstatus->status_msg); + FREE(idstatus); +} + +struct yahoo_packet *yahoo_parsepacket(struct yahoo_context *ctx, + struct yahoo_rawpacket *inpkt) +{ + struct yahoo_packet *pkt; + + /* If no valid inpkt passed, return */ + if (!inpkt) + { + return NULL; + } + + /* Allocate the packet structure, zeroed out */ + pkt = (struct yahoo_packet *) calloc(sizeof(*pkt), 1); + + /* Pull out the standard data */ + pkt->service = yahoo_makeint(inpkt->service); + pkt->connection_id = yahoo_makeint(inpkt->connection_id); + pkt->real_id = strdup(inpkt->nick1); + pkt->active_id = strdup(inpkt->nick2); + + pkt->magic_id = yahoo_makeint(inpkt->magic_id); + pkt->unknown1 = yahoo_makeint(inpkt->unknown1); + pkt->msgtype = yahoo_makeint(inpkt->msgtype); + + /* doing this seems like a cleaner approach, but am not sure if it is + a valid one */ + if (pkt->magic_id != 0) + { + ctx->magic_id = pkt->magic_id; + } + if (pkt->connection_id != 0) + { + ctx->connection_id = pkt->connection_id; + } + + /* Call a particular parse routine to pull out the content */ + switch (pkt->service) + { + case YAHOO_SERVICE_LOGON: + case YAHOO_SERVICE_LOGOFF: + case YAHOO_SERVICE_ISAWAY: + case YAHOO_SERVICE_ISBACK: + case YAHOO_SERVICE_USERSTAT: + case YAHOO_SERVICE_CHATLOGON: + case YAHOO_SERVICE_CHATLOGOFF: + case YAHOO_SERVICE_GAMELOGON: + case YAHOO_SERVICE_GAMELOGOFF: + yahoo_parsepacket_status(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_IDACT: + case YAHOO_SERVICE_IDDEACT: + /* nothing needs done, only has main fields */ + break; + case YAHOO_SERVICE_MESSAGE: + case YAHOO_SERVICE_SYSMESSAGE: + case YAHOO_SERVICE_CHATMSG: + yahoo_parsepacket_message(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_NEWMAIL: + case YAHOO_SERVICE_NEWPERSONALMAIL: + yahoo_parsepacket_newmail(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CALENDAR: + yahoo_parsepacket_calendar(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CHATINVITE: + yahoo_parsepacket_chatinvite(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_NEWCONTACT: + yahoo_parsepacket_newcontact(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_GROUPRENAME: + yahoo_parsepacket_grouprename(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CONFINVITE: + yahoo_parsepacket_conference_invite(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CONFLOGON: + case YAHOO_SERVICE_CONFLOGOFF: + yahoo_parsepacket_conference_user(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CONFDECLINE: + yahoo_parsepacket_conference_decline(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CONFADDINVITE: + yahoo_parsepacket_conference_addinvite(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_CONFMSG: + yahoo_parsepacket_conference_msg(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_PING: + yahoo_parsepacket_ping(ctx, pkt, inpkt); + break; + case YAHOO_SERVICE_FILETRANSFER: + yahoo_parsepacket_filetransfer(ctx, pkt, inpkt); + break; + default: + yahoo_dbg_Print("libyahoo", + "yahoo_parsepacket: can't parse packet type (%d)\n", + pkt->service); + break; + } + + return pkt; +} + +int yahoo_parsepacket_ping(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + + /* Make working copy of content */ + content = inpkt->content; + + pkt->msg = NULL; + if (content) + { + pkt->msg = strdup(content); + } + + return 0; +} + +int yahoo_parsepacket_newmail(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + int len; + + /* Make working copy of content */ + content = inpkt->content; + len = strlen(content); + + if (pkt->service == YAHOO_SERVICE_NEWMAIL) + { + pkt->mail_status = 0; + if (len > 0) + { + pkt->mail_status = atoi(content); + } + } + else if (pkt->service == YAHOO_SERVICE_NEWPERSONALMAIL) + { + pkt->mail_status = 0; + if (len > 0) + { + pkt->mail_status = atoi(content); + } + } + + return 0; +} + +int yahoo_parsepacket_grouprename(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp, delim[5]; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->group_old = NULL; + pkt->group_new = NULL; + + tmp = NULL; + delim[0] = 1; /* control-a */ + delim[1] = 0; + + if (content) + { + tmp = strtok(content, delim); + } + + if (tmp) /* got the conference id */ + { + pkt->group_old = strdup(tmp); + tmp = strtok(NULL, delim); + } + + if (tmp) /* conference host */ + { + pkt->group_new = strdup(tmp); + tmp = strtok(NULL, delim); + } + + FREE(content); + return (0); +} + +/* + +yahoo_parsepacket_conference_invite() + +Packet format: + id^host^invited-users^msg^0or1 + +Parses Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + char *conf_host == The person inviting you to conference. + char **userlist == Everyone else invited to conference. + Null terminated array of strings. + char *msg == Invitation message. + int conf_type == Type of conference ( 0 = text, 1 = voice ) + +*/ +int yahoo_parsepacket_conference_invite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp = 0; + size_t found = 0, len = yahoo_makeint(inpkt->len); + + /* Make working copy of content */ + content = memdup(inpkt->content, len); + + /* init elements to all null */ + pkt->conf_id = NULL; + pkt->conf_host = NULL; + pkt->conf_user = pkt->active_id; + pkt->conf_userlist = NULL; + pkt->conf_inviter = NULL; + pkt->conf_msg = NULL; + + if (content) + { + tmp = memtok(content, len, "\002", 2, &found); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* conference host */ + { + pkt->conf_host = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* who else is invited */ + { + char *userlist = memdupasstr(tmp, found); + + pkt->conf_userlist = yahoo_list2array(userlist); + FREE(userlist); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* msg */ + { + pkt->conf_msg = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* 0 == text chat 1 == voice chat */ + { + char *conftype = memdupasstr(tmp, found); + + if (0 != conftype) + pkt->conf_type = atoi(conftype); + FREE(conftype); + tmp = memtok(0, 0, "\002", 2, &found); + } + + FREE(content); + return 0; +} + +/* + +yahoo_parsepacket_conference_decline() + +Packet format: + id^user-who-declined^msg + +Parses Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + char *conf_user == User who declined. + char *msg == Reason for declining. + +*/ +int yahoo_parsepacket_conference_decline(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp, delim[2]; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->conf_id = NULL; + pkt->conf_host = NULL; + pkt->conf_user = NULL; + pkt->conf_userlist = NULL; + pkt->conf_inviter = NULL; + pkt->conf_msg = NULL; + + tmp = NULL; + delim[0] = 2; /* control-b */ + delim[1] = 0; + + if (content) + { + tmp = strtok(content, delim); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = strdup(tmp); + tmp = strtok(NULL, delim); + } + if (tmp) /* got the user who declined */ + { + pkt->conf_user = strdup(tmp); + tmp = strtok(NULL, delim); + } + if (tmp) /* msg */ + { + pkt->conf_msg = strdup(tmp); + tmp = strtok(NULL, delim); + } + + FREE(content); + return 0; + +} + +/* + +yahoo_parsepacket_conference_addinvite() + +Packet format: +Msgtype == 1 + id^inviter^who-else-invited^who-else-in-conf^msg^0or1 +Msgtype == 11 + id^inviter^invited-user + +Parses Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + char *conf_inviter == The person inviting you to conference. + char **userlist == Everyone else in conference. + Null terminated array of strings. + char *msg == Invitation message. + int conf_type == Type of conference ( 0 = text, 1 = voice ) + + char *conf_user == User invited to conference (msgtype == 11) +*/ +int yahoo_parsepacket_conference_addinvite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content = 0, *tmp = 0; + size_t found = 0, len = yahoo_makeint(inpkt->len); + + /* Make working copy of content */ + content = memdup(inpkt->content, len); + + /* init elements to all null */ + pkt->conf_id = NULL; + pkt->conf_host = NULL; + pkt->conf_user = NULL; + pkt->conf_userlist = NULL; + pkt->conf_inviter = NULL; + pkt->conf_msg = NULL; + + if (pkt->msgtype == 1) + { + if (content) + { + tmp = memtok(content, len, "\002", 2, &found); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + if (tmp) /* got the inviter */ + { + pkt->conf_inviter = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + if (tmp) /* got who-else-invited */ + { + /* don't use this field, its the same as the next one + so I'm going to use the second field */ + /* pkt->conf_userlist = yahoo_list2array(tmp); */ + tmp = memtok(0, 0, "\002", 2, &found); + } + if (tmp) /* got the people in conference + not counting the inviter */ + { + char *userlist = memdupasstr(tmp, found); + + pkt->conf_userlist = yahoo_list2array(userlist); + FREE(userlist); + tmp = memtok(0, 0, "\002", 2, &found); + } + if (tmp) /* got the message */ + { + pkt->conf_msg = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + if (tmp) /* 0 at the end */ + { + char *conftype = memdupasstr(tmp, found); + + if (0 != conftype) + pkt->conf_type = atoi(conftype); + FREE(conftype); + /* tmp = memtok (0, 0, "\002", 2, &found); */ + } + } + else + /* msgid == 11 (someone else is being invited) */ + { + if (content) + { + tmp = memtok(content, len, "\002", 2, &found); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* got the inviter */ + { + pkt->conf_inviter = memdupasstr(tmp, found); + tmp = memtok(0, 0, "\002", 2, &found); + } + + if (tmp) /* got the invited-user */ + { + pkt->conf_user = memdupasstr(tmp, found); + /* tmp = memtok (0, 0, "\002", 2, &found); */ + } + } + + FREE(content); + return 0; +} + +/* + +yahoo_parsepacket_conference_msg() + +Packet format: + id^who-from^msg + +Parses Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + char *conf_user == User who sent message. + char *msg == Message. + +*/ +int yahoo_parsepacket_conference_msg(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp, delim[5]; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->conf_id = NULL; + pkt->conf_host = NULL; + pkt->conf_user = NULL; + pkt->conf_userlist = NULL; + pkt->conf_inviter = NULL; + pkt->conf_msg = NULL; + + tmp = NULL; + delim[0] = 2; /* control-b */ + delim[1] = 0; + + /* parse error messages first */ + if (pkt->msgtype == YAHOO_MSGTYPE_ERROR) + { + FREE(content); + return 0; + } + + if (content) + { + tmp = strtok(content, delim); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = strdup(tmp); + tmp = strtok(NULL, delim); + } + + if (tmp) /* conference user */ + { + pkt->conf_user = strdup(tmp); + tmp = strtok(NULL, delim); + } + + if (tmp) /* msg */ + { + pkt->conf_msg = strdup(tmp); + tmp = strtok(NULL, delim); + } + + FREE(content); + return 0; +} + +/* + +yahoo_parsepacket_conference_user() + (User logged on/off to conference) +Packet format: + id^user_who_logged_on/off + +Parses Arguments: + char *conf_id == The conference id -- usually of the form name-number, + though it doesn't seem to matter much. ex: jaylubo-123 + char *conf_user == User who logged on to conference. + +*/ +int yahoo_parsepacket_conference_user(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp, delim[5]; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->conf_id = NULL; + pkt->conf_host = NULL; + pkt->conf_user = NULL; + pkt->conf_userlist = NULL; + pkt->conf_inviter = NULL; + pkt->conf_msg = NULL; + + tmp = NULL; + delim[0] = 2; /* control-b */ + delim[1] = 0; + + if (content) + { + tmp = strtok(content, delim); + } + + if (tmp) /* got the conference id */ + { + pkt->conf_id = strdup(tmp); + tmp = strtok(NULL, delim); + } + + if (tmp) /* conference user */ + { + pkt->conf_user = strdup(tmp); + tmp = strtok(NULL, delim); + } + + FREE(content); + return 0; +} + +int yahoo_parsepacket_filetransfer(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp[5]; + int i, j, section; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->file_from = NULL; + pkt->file_flag = NULL; + pkt->file_url = NULL; + pkt->file_expires = 0; + pkt->file_description = NULL; + + /* overkill allocation, but simple since only temporary use */ + tmp[0] = strdup(content); + tmp[1] = strdup(content); + tmp[2] = strdup(content); + tmp[3] = strdup(content); + tmp[4] = strdup(content); + + /* raw data format: from,flag,url,timestamp,description */ + + i = 0; + j = 0; + section = 0; + tmp[0][0] = 0; + tmp[1][0] = 0; + tmp[2][0] = 0; + tmp[3][0] = 0; + tmp[4][0] = 0; + + while (i < strlen(content)) + { + char ch = content[i]; + + if (ch == ',' && section < 4) + { + j = 0; + section++; + } + else + { + tmp[section][j++] = ch; + tmp[section][j] = 0; + } + i++; + } + + /* do stuff with extracted parts */ + pkt->file_from = strdup(tmp[0]); + pkt->file_flag = strdup(tmp[1]); + pkt->file_url = strdup(tmp[2]); + pkt->file_expires = atoi(tmp[3]); + pkt->file_description = strdup(tmp[4]); + + /* free working variables */ + FREE(tmp[0]); + FREE(tmp[1]); + FREE(tmp[2]); + FREE(tmp[3]); + FREE(tmp[4]); + FREE(content); + return 0; +} + +int yahoo_parsepacket_calendar(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp, delim[5]; + + /* Make working copy of content */ + content = strdup(inpkt->content); + + /* init elements to all null */ + pkt->cal_url = NULL; + pkt->cal_timestamp = NULL; + pkt->cal_type = 0; + pkt->cal_title = NULL; + pkt->cal_description = NULL; + + tmp = NULL; + delim[0] = 2; /* control-b */ + delim[1] = 0; + + if (content) + { + tmp = strtok(content, delim); + } + + if (tmp) /* got the url */ + { + pkt->cal_url = strdup(tmp); + tmp = strtok(NULL, delim); + +/* + v= is not the type code + i= doesn't look like it either + tmp2 = strstr(pkt->cal_url, "v="); + if ( tmp2 ) + { + pkt->cal_type = atoi(tmp2); + } + */ + + } + + if (tmp) /* unknown (type code?) */ + { +/* appears this isn't it either, I don't see where it is */ +/* pkt->cal_type = atoi(tmp); */ + tmp = strtok(NULL, "\r\n"); + } + + if (tmp) /* timestamp */ + { + pkt->cal_timestamp = strdup(tmp); + tmp = strtok(NULL, "\r\n"); + } + + if (tmp) /* title */ + { + pkt->cal_title = strdup(tmp); + tmp = strtok(NULL, delim); /* use delim since it won't occur again */ + } + + if (tmp) + { + pkt->cal_description = strdup(tmp); + } + + FREE(content); + return 0; +} + +int yahoo_parsepacket_chatinvite(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + int len; + + /* Make working copy of content */ + content = strdup(inpkt->content); + len = strlen(content); + + /* do special parsing for invite later on */ + pkt->chat_invite_content = strdup(content); + + return 0; +} + +int yahoo_parsepacket_newcontact(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + int len; + + /* Make working copy of content */ + content = strdup(inpkt->content); + len = strlen(content); + + /* cheat for now, say if first digit is number */ + if (len > 0) + { + if (isdigit((int) content[0])) + { + return yahoo_parsepacket_status(ctx, pkt, inpkt); + } + else + { + return yahoo_parsepacket_message(ctx, pkt, inpkt); + } + } + + return 0; +} + +int yahoo_parsepacket_status(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmpc; + char *tmp1; + int i; + int len; + int index; + int realcount; + + /* Make working copy of content */ + content = strdup(inpkt->content); + len = strlen(content); + + /* Pull off the flag from the initial part of the content */ + /* this flag indicates the number of buddy that're online */ + pkt->flag = 0; + tmpc = content; + while (tmpc[0] && isdigit((int) tmpc[0])) + { + pkt->flag = pkt->flag * 10 + (content[0] - '0'); + tmpc++; + } + if (tmpc[0] && tmpc[0] == ',') + { + tmpc++; + } + + /* + We're receiving either this: + 2,buddy1(0,728EE9FB,0,1,0,0),buddy2(0,7AC00000,0,1,0,0) + or this: + buddy1(0,728EE9FB,0,1,0,0) + hence: + */ + + if (pkt->flag == 0) + { + pkt->idstatus_count = 1; + } + else + { + pkt->idstatus_count = pkt->flag; + } + + /* print an error if I get the was not AWAY */ + if (strstr(tmpc, "was not AWAY")) + { + pkt->idstatus_count = 0; + yahoo_dbg_Print("libyahoo", "yahoo_parsepacket_status: " + "got a 'was not AWAY' message\n"); + } + + if (pkt->idstatus_count == 0) + { + /* No entries, so no array needed */ + pkt->idstatus = NULL; + } + else + { + /* Allocate the array */ + pkt->idstatus = (struct yahoo_idstatus **) + calloc(sizeof(struct yahoo_idstatus), pkt->idstatus_count); + + for (i = 0; i < pkt->idstatus_count; i++) + { + pkt->idstatus[i] = (struct yahoo_idstatus *) + + calloc(1, sizeof(struct yahoo_idstatus)); + } + } + + index = 0; + tmp1 = NULL; + realcount = 0; + while (tmpc && tmpc[0] && pkt->idstatus) + { + struct yahoo_idstatus *tmpid; + + /* Get pointer to allocated structure to hold status data */ + tmpid = pkt->idstatus[index++]; + if (!tmpid) + { + /* shortcut, we know there can't be any more status entries + at this point */ + /* yahoo_dbg_Print("status", "null tmpid"); */ + break; + } + + /* YPNS2.0 nick(status,msg,connection_id,UNK,in_pager,in_chat,in_game) */ + /* tnneul(99,test,message^A,6AD68325,0,1,0,0) */ + /* 0 1 2 3 4 5 6 */ + + /* YPNS1.0 nick(status,connection_id,UNK,in_pager,in_chat,in_game) */ + /* nneul(0,7081F531,0,1,0,0) */ + /* 0 2 3 4 5 6 */ + + /* rewrite this whole section in a less ugly fashion */ + /* first pull off the id */ + + /* YUCK - YPNS2.0 has variable format status records, if type is 99, + it has 7 fields, second is msg */ + +#if 0 + yahoo_dbg_Print("status", "whole string = '%s'\n", + yahoo_dbg_NullCheck(tmpc)); +#endif + + if (tmp1) + { + tmp1 = strtok(NULL, "("); + } + else + { + tmp1 = strtok(tmpc, "("); + } + if (tmp1 && tmp1[0] == ',') + { + tmp1++; + } + + if (tmp1) + { + tmpid->id = strdup(tmp1); + realcount++; + + for (i = 0; i <= 6 && tmp1; i++) + { +#if 0 + yahoo_dbg_Print("status", "i==%d\n", i); +#endif + + if (i == 6) /* end of status area */ + { + tmp1 = strtok(NULL, "),"); + } + else if (i == 1) + { + char delim[3]; + + if (tmpid->status == YAHOO_STATUS_CUSTOM) + { + delim[0] = 1; + delim[1] = ','; + delim[1] = 0; + tmp1 = strtok(NULL, delim); + } + else + { + i = 2; + tmp1 = strtok(NULL, ","); + } + } + else + { + + tmp1 = strtok(NULL, ","); + } + + /* then pull off the particular element of the list */ + if (tmp1) + { + switch (i) + { + case 0: /* status */ + tmpid->status = atoi(tmp1); + break; + case 1: /* msg */ + if (tmpid->status == YAHOO_STATUS_CUSTOM) + { + tmpid->status_msg = strdup(tmp1); + } + break; + case 2: /* session id */ + tmpid->connection_id = strdup(tmp1); + break; + case 3: /* dunno what this is */ + break; + case 4: + tmpid->in_pager = atoi(tmp1); + break; + case 5: + tmpid->in_chat = atoi(tmp1); + break; + case 6: + tmpid->in_game = atoi(tmp1); + break; + } + } + } + } + } + + for (i = realcount; i <= pkt->idstatus_count; i++) + { + if (pkt->idstatus && pkt->idstatus[i]) + { + FREE(pkt->idstatus[i]); + } + } + pkt->idstatus_count = realcount; + + /* Free working copy of content */ + FREE(content); + + /* Return ok for success */ + return (0); +} + +int yahoo_parsepacket_message(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *tmp_id; + int i, j, section; + + if (pkt->msgtype == YAHOO_MSGTYPE_OFFLINE) + { + return yahoo_parsepacket_message_offline(ctx, pkt, inpkt); + } + + /* Make working copy of content */ + content = strdup(inpkt->content); + tmp_id = strdup(content); + + /* initialize */ + pkt->msg_status = 0; + + /* possible message content formats: */ +/* userid(#) *//* msgtype == YAHOO_MSGTYPE_STATUS */ + /* userid,,msg */ + + /* this needed butchered */ + /* YAHOO_MSGTYPE_OFFLINE */ + /* 6,6,tnneul,nneul,Tue Mar 7 12:14:50 2000,test offline msg^A */ + + i = 0; + j = 0; + section = 0; + tmp_id[0] = 0; + while (i < strlen(content)) + { + char ch = content[i]; + + if (section == 0) /* parsing userid */ + { + if (ch == ',') + { + j = 0; + section = 1; + } + else if (ch == '(') + { + j = 0; + section = 2; + } + else + { + tmp_id[j++] = ch; + tmp_id[j] = 0; + } + } + else if (section == 1) /* parsing flag */ + { + if (ch == ',') + { + j = 0; + section = 3; + } + } + else if (section == 2) /* parsing status */ + { + if (ch == ')') + { + j = 0; + section = 3; + } + else + { + if (isdigit((int) ch)) + { + pkt->msg_status *= 10; + pkt->msg_status += ch - '0'; + } + } + } + else + { + pkt->msg = strdup(&content[i]); + break; + } + + i++; + } + + /* do stuff with extracted parts */ + pkt->msg_id = strdup(tmp_id); + + /* handle empty message case */ + /* don't pass a message if it's just a status update */ + if (!pkt->msg && pkt->msgtype != YAHOO_MSGTYPE_STATUS) + { + pkt->msg = strdup(""); + } + + /* free working variables */ + FREE(tmp_id); + FREE(content); + + /* Return ok for success */ + return (0); +} + +/* This parses a special format offline message, and is only currently +called from yahoo_parsepacket_message. */ +int yahoo_parsepacket_message_offline(struct yahoo_context *ctx, + struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt) +{ + char *content; + char *to_id; + char *from_id; + char *timestamp; + int i, j, section; + + /* Make working copy of content */ + content = strdup(inpkt->content); + to_id = strdup(content); + from_id = strdup(content); + timestamp = strdup(content); + + /* initialize */ + pkt->msg_status = 0; + + /* 6,6,tnneul,nneul,Tue Mar 7 12:14:50 2000,test offline msg^A */ + /* sec0,sec1,sec2=to,sec3=from,sec4=tstamp,sec5=msg */ + + i = 0; + j = 0; + section = 0; + to_id[0] = 0; + from_id[0] = 0; + timestamp[0] = 0; + + while (i < strlen(content)) + { + char ch = content[i]; + + if (section == 0) /* parsing first unknown number */ + { + if (ch == ',') + { + j = 0; + section = 1; + } + } + else if (section == 1) /* parsing second unknown number */ + { + if (ch == ',') + { + j = 0; + section = 2; + } + } + else if (section == 2) /* parsing to-id */ + { + if (ch == ',') + { + j = 0; + section = 3; + } + else + { + to_id[j++] = ch; + to_id[j] = 0; + } + } + else if (section == 3) /* parsing from-id */ + { + if (ch == ',') + { + j = 0; + section = 4; + } + else + { + from_id[j++] = ch; + from_id[j] = 0; + } + } + else if (section == 4) /* parsing timestamp */ + { + if (ch == ',') + { + j = 0; + section = 5; + } + else + { + timestamp[j++] = ch; + timestamp[j] = 0; + } + } + else + { + pkt->msg = strdup(&content[i]); + break; + } + + i++; + } + + /* do stuff with extracted parts */ + pkt->msg_id = strdup(from_id); + pkt->msg_timestamp = strdup(timestamp); + if (pkt->active_id) + { + FREE(pkt->active_id); + pkt->active_id = strdup(to_id); + } + + /* free working variables */ + FREE(timestamp); + FREE(from_id); + FREE(to_id) FREE(content); + + /* Return ok for success */ + return (0); +} + +int yahoo_getdata(struct yahoo_context *ctx) +{ + char buf[1000]; + int res; + + /* This is a http mode connection, so just send a ping to get any + new data from the server. */ + if (ctx->connect_mode == YAHOO_CONNECT_HTTP || + ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0); + return (1); + } + + /* this assumes that data is ready */ + /* Read from the connection to the server and get any new data */ + res = read(ctx->sockfd, buf, 1000); + if (res == -1) + { + yahoo_dbg_Print("io", + "yahoo_getdata: error reading data from server\n"); + return (0); + } + if (res > 0) + { + yahoo_addtobuffer(ctx, buf, res); + yahoo_dbg_Print("io", "[libyahoo] yahoo_getdata: read (%d) bytes\n", + res); + return 1; + } + else if (res == 0) + { + yahoo_dbg_Print("io", + "[libyahoo] yahoo_getdata: got zero length read\n", res); + return 0; + } + + return (1); +} + +struct yahoo_rawpacket *yahoo_getpacket(struct yahoo_context *ctx) +{ + struct yahoo_rawpacket *pkt; + struct yahoo_rawpacket *retpkt; + int *buflen = &ctx->io_buf_curlen; + char *buffer = ctx->io_buf; + unsigned int contentlen; + + /* If buffer doesn't start with YHOO, skip bytes until it + does. This is to protect against possible packet alignment + errors if I size something wrong at any time. */ + + while ((*buflen >= 4) && (memcmp(buffer, "YHOO", 4))) + { +/* making quiet for now so I don't have to work too hard on the HTTP support */ +#if 0 + printf("\nskipped buffer byte (%d)\n", buffer[0]); +#endif + memmove(buffer, buffer + 1, *buflen - 1); + *buflen = *buflen - 1; + } + + /* Don't do anything if the buffer doesn't have at least a full + header */ + if (*buflen < YAHOO_PACKET_HEADER_SIZE) + { +// printf("returning null cause buffer is too small\n"); + return NULL; + } + +/* print out the beginning of the buffer */ +#if 0 + printf("Buffer (buflen = %d):\n", *buflen); + for (i = 0; i < *buflen; i++) + { + if ((i) % 10 == 0) + { + printf("\n%.4d: ", i); + } + if (isprint(buffer[i])) + { + printf("%-3d %c ", buffer[i], buffer[i]); + } + else + { + printf("%-3d ", buffer[i]); + } + } + printf("\n"); +#endif + /* Make pkt point to buffer for ease of use */ + pkt = (struct yahoo_rawpacket *) buffer; + + /* Determine the content size specified by the header */ + contentlen = yahoo_makeint(pkt->len) - YAHOO_PACKET_HEADER_SIZE; +// printf("contentlen = %d\n", contentlen); + + /* Don't continue if buffer doesn't have full content in it */ + if (*buflen < (YAHOO_PACKET_HEADER_SIZE + contentlen)) + { +// printf("buffer not big enough for contentlen\n"); + return NULL; + } + + /* Copy this packet */ + retpkt = + (struct yahoo_rawpacket *) malloc(YAHOO_PACKET_HEADER_SIZE + + contentlen); + memcpy(retpkt, buffer, YAHOO_PACKET_HEADER_SIZE + contentlen); + + /* Shift the buffer */ + memmove(buffer, buffer + YAHOO_PACKET_HEADER_SIZE + contentlen, + *buflen - YAHOO_PACKET_HEADER_SIZE - contentlen); + + /* Adjust the buffer length */ + *buflen -= (YAHOO_PACKET_HEADER_SIZE + contentlen); + + /* Return the packet */ + return retpkt; +} + +int yahoo_isbuddy(struct yahoo_context *ctx, const char *id) +{ + int i; + char *buddy = NULL; + + if (!id || !ctx || !ctx->buddies) + { + return FALSE; + } + + for (i = 0; ctx->buddies[i]; i++) + { + buddy = (ctx->buddies[i])->id; + if (!strcasecmp(id, buddy)) + { + return TRUE; + } + } + + return FALSE; +} + +static void yahoo_free_address (struct yahoo_address *add) +{ + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_free_address: record at address 0x%08p for user %s (%s %s) being free'd\n", + add, add->id, add->firstname, add->lastname); + + FREE (add->firstname); + FREE (add->lastname); + FREE (add->emailnickname); + FREE (add->email); + FREE (add->workphone); + FREE (add->homephone); +} + +void yahoo_freeaddressbook(struct yahoo_context *ctx) +{ + unsigned int count = ctx->address_count; + struct yahoo_address *add_p = ctx->addresses; + + if (NULL == ctx || NULL == ctx->addresses) + return; + + while (count-- > 0) + { + yahoo_free_address (add_p++); + } + + ctx->address_count = 0; + FREE (ctx->addresses); +} + +static void yahoo_data_to_addressbook (char *block, struct yahoo_context *ctx) +{ + char *token = NULL; + int record = 0; + struct yahoo_address *add = NULL; + + if (NULL == block || NULL == ctx) + return; + + yahoo_freeaddressbook (ctx); + + add = ctx->addresses = calloc (ctx->address_count, sizeof (struct yahoo_address)); + + /* + Okay! + At this point we have a char * (block) that has \012 delimited records + Each record (as a string when retreived with strtok) follows the format: + <ID>:<FIRSTNAME>\011<LASTNAME>\011<EMAILNICKNAME>\011<EMAIL>\011<HOMEPHONE>\011<WORKPHONE>\011[01]\011<ENTRYID>\000 + */ + + token = strtok (block, "\012"); + while (NULL != token) + { + /* + Here we must use memtok because we'll get some repeated tokens!!!!! + */ + char *field = NULL; + size_t token_len = 0, found = 0; + + ++record; + token_len = strlen (token); + + field = memtok(token, token_len, ":", 1, &found); + + if (NULL != field) + { + add->id = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->firstname = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->lastname = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->emailnickname = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->email = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->homephone = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->workphone = memdupasstr(field, found); + field = memtok(0, 0, "\011", 1, &found); + } + + if (NULL != field) + { + add->primary_phone = (*field == '0' ? home : work); + field = memtok(0, 0, "", 1, &found); + } + + if (NULL != field) + { + char *entryid = memdupasstr(field, found); + if (NULL != entryid) + { + add->entryid = atoi (entryid); + FREE (entryid); + } + } + + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: record #%d is for user %s (%s %s)\n", + record, add->id, add->firstname, add->lastname); + + ++add; + + token = strtok (NULL, "\012"); + } +} + +/* retreive the details of the friends in your address book that have a Yahoo! id listed */ +int yahoo_fetchaddressbook(struct yahoo_context *ctx) +{ + char buffer[5000]; + int servfd; + int res; + int copied = 0, size = 5000; + char *address = NULL, *copy = NULL; + + if (!ctx) + { + return 0; + } + + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: starting\n"); + + /* Check for cached addresses */ + if (ctx->addresses) + { + yahoo_freeaddressbook(ctx); + } + + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port); + } + else + { + servfd = yahoo_socket_connect(ctx, YAHOO_ADDRESS_HOST, YAHOO_ADDRESS_PORT); + } + + if (!servfd) + { + printf("[libyahoo] failed to connect to address book server.\n"); + return (0); + } + + strcpy(buffer, "GET "); + if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY) + { + strcat(buffer, YAHOO_ADDRESS_HOST); + } + strcat(buffer, "/yab/uk/yab?v=PG&A=s"); + strcat(buffer, " HTTP/1.0\r\n"); + strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n"); + strcat(buffer, "Host: " YAHOO_AUTH_HOST "\r\n"); + strcat(buffer, "Cookie: "); + strcat(buffer, ctx->cookie); + strcat(buffer, "\r\n"); + strcat(buffer, "\r\n"); + + write(servfd, buffer, strlen(buffer)); + + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: writing buffer '%s'\n", buffer); + + while ((res = yahoo_tcp_readline(buffer, 5000, servfd)) > 0) + { + if ('\012' == buffer[0]) + continue; + + if (0 == strncmp (buffer, "1\011", 2)) + { + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: found first line\n"); + if (3 == res) + { + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: however there's been a problem\n"); + break; + } + + address = &buffer[2]; + } + else if (NULL != address) + { + address = &buffer[0]; + } + + if (NULL != address) + { + if (NULL == copy) + { + copy = malloc (size); + memset (copy, 0, size); + } + + if ((copied + res) > size) + { + char *newcopy = NULL; + + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: resizing buffer from %d bytes to %d bytes\n", size, size * 2); + size *= 2; + newcopy = malloc (size); + memset (newcopy, 0, size); + memcpy (newcopy, copy, copied); + free (copy); + copy = newcopy; + } + + copied += res; + strcat (copy, address); + ++ctx->address_count; + } + } + + yahoo_data_to_addressbook (copy, ctx); + FREE (copy); + + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: closing server connection\n"); + close(servfd); + servfd = 0; + yahoo_dbg_Print("addressbook", + "[libyahoo] yahoo_fetchaddressbook: closed server connection\n"); + + yahoo_dbg_Print("addressbook", "[libyahoo] yahoo_fetchaddressbook: done (%d addresses retreived)\n", ctx->address_count); + + return ctx->address_count; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/libyahoo.h Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,284 @@ +#ifndef LIBYAHOO_H +#define LIBYAHOO_H + +/* Service constants */ +#define YAHOO_SERVICE_LOGON 1 +#define YAHOO_SERVICE_LOGOFF 2 +#define YAHOO_SERVICE_ISAWAY 3 +#define YAHOO_SERVICE_ISBACK 4 +#define YAHOO_SERVICE_IDLE 5 +#define YAHOO_SERVICE_MESSAGE 6 +#define YAHOO_SERVICE_IDACT 7 +#define YAHOO_SERVICE_IDDEACT 8 +#define YAHOO_SERVICE_MAILSTAT 9 +#define YAHOO_SERVICE_USERSTAT 10 +#define YAHOO_SERVICE_NEWMAIL 11 +#define YAHOO_SERVICE_CHATINVITE 12 +#define YAHOO_SERVICE_CALENDAR 13 +#define YAHOO_SERVICE_NEWPERSONALMAIL 14 +#define YAHOO_SERVICE_NEWCONTACT 15 +#define YAHOO_SERVICE_ADDIDENT 16 +#define YAHOO_SERVICE_ADDIGNORE 17 +#define YAHOO_SERVICE_PING 18 +#define YAHOO_SERVICE_GROUPRENAME 19 +#define YAHOO_SERVICE_SYSMESSAGE 20 +#define YAHOO_SERVICE_PASSTHROUGH2 22 +#define YAHOO_SERVICE_CONFINVITE 24 +#define YAHOO_SERVICE_CONFLOGON 25 +#define YAHOO_SERVICE_CONFDECLINE 26 +#define YAHOO_SERVICE_CONFLOGOFF 27 +#define YAHOO_SERVICE_CONFADDINVITE 28 +#define YAHOO_SERVICE_CONFMSG 29 +#define YAHOO_SERVICE_CHATLOGON 30 +#define YAHOO_SERVICE_CHATLOGOFF 31 +#define YAHOO_SERVICE_CHATMSG 32 +#define YAHOO_SERVICE_GAMELOGON 40 +#define YAHOO_SERVICE_GAMELOGOFF 41 +#define YAHOO_SERVICE_FILETRANSFER 70 + +/* Yahoo style/color directives */ +#define YAHOO_COLOR_BLACK "\033[30m" +#define YAHOO_COLOR_BLUE "\033[31m" +#define YAHOO_COLOR_LIGHTBLUE "\033[32m" +#define YAHOO_COLOR_GRAY "\033[33m" +#define YAHOO_COLOR_GREEN "\033[34m" +#define YAHOO_COLOR_PINK "\033[35m" +#define YAHOO_COLOR_PURPLE "\033[36m" +#define YAHOO_COLOR_ORANGE "\033[37m" +#define YAHOO_COLOR_RED "\033[38m" +#define YAHOO_COLOR_OLIVE "\033[39m" +#define YAHOO_STYLE_ITALICON "\033[2m" +#define YAHOO_STYLE_ITALICOFF "\033[x2m" +#define YAHOO_STYLE_BOLDON "\033[1m" +#define YAHOO_STYLE_BOLDOFF "\033[x1m" +#define YAHOO_STYLE_UNDERLINEON "\033[4m" +#define YAHOO_STYLE_UNDERLINEOFF "\033[x4m" +#define YAHOO_STYLE_URLON "\033[lm" +#define YAHOO_STYLE_URLOFF "\033[xlm" + +/* Message flags */ +#define YAHOO_MSGTYPE_ERROR -1 /* 0xFFFFFFFF */ +#define YAHOO_MSGTYPE_NONE 0 /* ok */ +#define YAHOO_MSGTYPE_NORMAL 1 /* notify */ +#define YAHOO_MSGTYPE_BOUNCE 2 /* not available */ +#define YAHOO_MSGTYPE_STATUS 4 /* user away */ +#define YAHOO_MSGTYPE_OFFLINE 5 +#define YAHOO_MSGTYPE_INVISIBLE 12 + +#define YAHOO_MSGTYPE_KNOWN_USER 1515563606 /* 0x5A55AA56 */ +#define YAHOO_MSGTYPE_UNKNOWN_USER 1515563605 /* 0x5A55AA55 */ + +#define YAHOO_CONF_LEVEL_0 0 + +/* Structure definitions */ + +enum phone { home = 0, work }; + +struct yahoo_address +{ + char *id; + char *firstname; + char *lastname; + char *emailnickname; + char *email; + char *workphone; + char *homephone; + enum phone primary_phone; + unsigned int entryid; +}; + +struct yahoo_context +{ + /* Input parameters from calling application */ + char *user; + char *password; + int connect_mode; /* connection mode */ + int proxy_port; + char *proxy_host; + + /* Semi-public */ + int sockfd; /* pager server socket */ + + /* IO buffer parameters */ + char *io_buf; /* Buffer for storing incoming packets */ + int io_buf_curlen; + int io_buf_maxlen; + + /* Cookie data */ + char *cookie; + char *login_cookie; + + /* Buddy list parameters */ + struct yahoo_buddy **buddies; /* list of groups and buddies */ + char **identities; /* list of identities */ + char *login_id; /* what id should be specified as the primary id */ + int mail; /* I think this indicates if user has a yahoo mail id */ + + /* Temporary to hold the magic id for outbound packets */ + unsigned int magic_id; + unsigned int connection_id; + unsigned int address_count; + struct yahoo_address *addresses; +}; + +struct yahoo_options +{ + int connect_mode; + + char *proxy_host; + int proxy_port; +}; + +struct yahoo_rawpacket +{ + char version[8]; /* 7 chars and trailing null */ + unsigned char len[4]; /* length - little endian */ + unsigned char service[4]; /* service - little endian */ + +/* 3 X 4bytes - host, port, ip_address */ +/* not sure what diff is between host and ip addr */ + unsigned char connection_id[4]; /* connection number - little endian */ + unsigned char magic_id[4]; /* magic number used for http session */ + unsigned char unknown1[4]; + + unsigned char msgtype[4]; + char nick1[36]; + char nick2[36]; + char content[1]; /* was zero, had problems with aix xlc */ +}; + +/* + * Structure for returning the status/flags/etc. of a particular id + */ +struct yahoo_idstatus +{ + char *id; + int status; + char *status_msg; + char *connection_id; + int in_pager; + int in_chat; + int in_game; /* not sure */ +}; + +/* + * Structure for returning a buddy entry + */ +struct yahoo_buddy +{ + char *group; /* member of what group */ + char *id; /* the buddy's id */ +}; + +/* + * Generic packet type for returning from the parse routine + * The fields in this packet are not all used and are defined + * so that a single type of packet can be returned from the parse routine + */ + +struct yahoo_packet +{ + /* Common info */ + int service; /* Service type */ + int connection_id; /* Connection ID */ + char *real_id; /* What ID is logged on */ + char *active_id; /* What ID is active */ + + /* Flags for the unknown portion of the data */ + unsigned int magic_id; + unsigned int unknown1; + unsigned int msgtype; /* flag for indicating/requesting msg type */ + + /* Status flag, I think used at login */ + int flag; /* Used at logon for success/alerts? */ + + /* Status entries */ + int idstatus_count; + struct yahoo_idstatus **idstatus; /* Array of status entries for id's */ + + /* Conferencing */ + char *conf_id; /* id for the conference */ + char *conf_host; /* who is hosting the conference */ + char *conf_user; /* single username ( used in */ + /* declined conference/ */ + /* addinvite / message / */ + /* logon / logoff ) */ + + char **conf_userlist; /* user list */ + char *conf_inviter; /* user who invited you */ + /* (conference addinvite) */ + + char *conf_msg; /* conference message */ + + int conf_type; /* text(0) or */ + /* voice(1) conference */ + + /* Mail status */ + int mail_status; + + /* Calendar data */ + char *cal_url; + int cal_type; + char *cal_timestamp; + char *cal_title; + char *cal_description; + + /* Chat invite data */ + char *chat_invite_content; + + /* Received message */ + char *msg_id; /* Originator of message */ + int msg_status; /* Status update from the message */ + char *msg_timestamp; /* Timestamp of offline message */ + char *msg; /* Content of message */ + + /* File transfer request */ + char *file_from; + char *file_flag; + char *file_url; + char *file_description; + int file_expires; + + /* Group names for renaming */ + char *group_old; /* Old group name */ + char *group_new; /* New group name */ +}; + +/* Misc contants */ +#define YAHOO_PACKET_HEADER_SIZE 104 /* size of a standard header */ + +/* Status codes */ +struct yahoo_idlabel +{ + int id; + char *label; +}; + +/* Constants for connect mode selection */ +enum +{ + YAHOO_CONNECT_NORMAL, YAHOO_CONNECT_HTTP, YAHOO_CONNECT_HTTPPROXY, + YAHOO_CONNECT_SOCKS4, YAHOO_CONNECT_SOCKS5 +}; + +/* Constants for status codes */ +enum +{ + YAHOO_STATUS_AVAILABLE, + YAHOO_STATUS_BRB, + YAHOO_STATUS_BUSY, + YAHOO_STATUS_NOTATHOME, + YAHOO_STATUS_NOTATDESK, + YAHOO_STATUS_NOTINOFFICE, + YAHOO_STATUS_ONPHONE, + YAHOO_STATUS_ONVACATION, + YAHOO_STATUS_OUTTOLUNCH, + YAHOO_STATUS_STEPPEDOUT, + YAHOO_STATUS_INVISIBLE = 12, + YAHOO_STATUS_CUSTOM = 99, + YAHOO_STATUS_IDLE = 999 +}; + +/* Function prototypes */ +#include "libyahoo-proto.h" +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/memtok.c Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,114 @@ +/* Standard system headers */ +#include <stdlib.h> +#include <string.h> + +/* + * memtok differs from strtok in a few ways: + * The pointer to the buffer to be scanned AND the pointer to the delimiters are NOT NULL terminated + * strings but are each a pair of a pointer and byte count (so that NIL characters can be contained + * in either of these buffers! + * + * Also memtok does not replace the "found" delimiter with a NIL character, but places the number + * of bytes delimited by that delimiter into the location of the size_t pointer to by found. + * + * The whole **real** point of this function was that strtok skips any repeating delimiters, but we + * need a function that retuns "empty strings" should there be two delimiters in a row. + * + * For some sense of consistency, the byte count of the buffer to be searched through is ALSO ignored + * by memtok iff the buffer to be scanned is NULL + * + * Here's an example: + * + * size_t found = 0; + * char *tok = 0, *buffer = malloc (COUNT); + * fill_buffer_with_some_data (buffer, COUNT); + * tok = memtok (buffer, COUNT, "\000\002", 2, &found); + * + * if tok != NULL then the bytes from tok to (tok + found) are the token + * You can then look for more tokens with: + * + * tok = memtok (NULL, 0, "\000\002", 2, &found); + * + * If tmp == NULL noone of the delimiters were found, however tmp can != NULL and found CAN == 0 + * + * This means that although a delimiter was found it was immediately preceded by another delimiter and + * thus delimited an empty token. + * + * ( As it happens, if one of the delimiters you want to search for is a NIL character, you can put the + * other delimiter characters in a string literal and "lie" about how many delimiter characters there are + * because all string literals are NIL terminated! + * + * Therefor the above example could have been written: + * tok = memtok (buffer, COUNT, "\002", 2, &found); + * + * There are also two supplimentary functions that make using these tokens easier + * + * memdup is akin to strdup except that instead of it looking for a NIL termination character + * it simply mallocs copies the specified number of bytes + * + * memdupasstr does as memdup except that it mallocs 1 more byte and makes it a NIL char so that you + * can treat it as a string (as long as you're sure that the memory being described by the pointer and + * byte count don't already contain any NIL characters) + * + */ + +/**********************************************************************************************************************************/ +/* Interface (global) functions */ +/**********************************************************************************************************************************/ +char *memtok(char *m, size_t bytes, const char *delims, size_t delim_count, + size_t * found) +{ + static char *mem = 0, *c = 0; + static size_t offset = 0, offset_now = 0, limit = 0; + + if (0 != m) + { + mem = m; + offset = 0; + limit = bytes; + } + + offset_now = offset; + + for (c = mem; offset < limit; ++offset, ++c) + { + if (0 != memchr(delims, *c, delim_count)) + { + static char *ret = 0; + + ret = mem; + mem = c + 1; + *found = offset - offset_now; + offset_now = offset + 1; + return ret; + } + } + + return 0; +} + +char *memdup(const char *mem, size_t bytes) +{ + char *dup = 0; + + if (0 < bytes && 0 != mem) + { + dup = malloc(bytes); + memcpy(dup, mem, bytes); + } + + return dup; +} + +char *memdupasstr(const char *mem, size_t bytes) +{ + char *string = 0; + + if (0 < bytes && 0 != mem) + { + string = memdup(mem, bytes + 1); + string[bytes] = '\0'; + } + + return string; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/memtok.h Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,8 @@ +#ifndef MEMTOK_H +#define MEMTOK_H + +char *memtok (char *m, size_t bytes, const char *delims, size_t delim_count, size_t *found); +char *memdup (const char *mem, size_t bytes); +char *memdupasstr (const char *mem, size_t bytes); + +#endif /* ndef MEMTOK_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/yay/yay.c Fri Nov 03 10:03:53 2000 +0000 @@ -0,0 +1,351 @@ +/* + * gaim + * + * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> + * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx> + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + + +#include <netdb.h> +#include <gtk/gtk.h> +#include <unistd.h> +#include <errno.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include "multi.h" +#include "prpl.h" +#include "gaim.h" +#include "libyahoo.h" + +struct yahoo_data { + struct yahoo_context *ctxt; +}; + +static char *yahoo_name() { + return "Yahoo"; +} + +char *name() { + return "Yahoo"; +} + +char *description() { + return "Allows gaim to use the Yahoo protocol"; +} + +static void process_packet_status(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + int i; + + if (pkt->service == YAHOO_SERVICE_LOGOFF && !strcasecmp(pkt->active_id, gc->username)) { + signoff(gc); + return; + } + + for (i = 0; i < pkt->idstatus_count; i++) { + struct group *g; + struct buddy *b; + struct yahoo_idstatus *rec = pkt->idstatus[i]; + + b = find_buddy(gc, rec->id); + if (!b) { + struct yahoo_buddy **buddy; + for (buddy = yd->ctxt->buddies; *buddy; buddy++) { + struct yahoo_buddy *bud = *buddy; + + if (!strcasecmp(rec->id, bud->id)) + b = add_buddy(gc, bud->group, bud->id, bud->id); + } + } + if (pkt->service == YAHOO_SERVICE_LOGOFF) + serv_got_update(gc, b->name, 0, 0, 0, 0, 0, 0); + else + serv_got_update(gc, b->name, 1, 0, 0, 0, rec->status, 0); + } +} + +static void process_packet_message(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + if (pkt->msg) { + if (pkt->msgtype == YAHOO_MSGTYPE_BOUNCE) + do_error_dialog("Your message did not get received.", "Error"); + else + serv_got_im(gc, pkt->msg_id, pkt->msg, pkt->msg_timestamp ? 1 : 0); + } +} + +static void process_packet_conf_invite(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +} + +static void process_packet_conf_add_invite(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +} + +static void process_packet_conf_msg(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +} + +static void process_packet_conf_logon(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +} + +static void process_packet_conf_logoff(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +} + +static void process_packet_newmail(struct gaim_connection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + char buf[2048]; + + if (pkt->mail_status) { + if (pkt->service == YAHOO_SERVICE_NEWMAIL) + g_snprintf(buf, sizeof buf, "%s has %d new message%s on Yahoo Mail.", + gc->username, pkt->mail_status, + pkt->mail_status == 1 ? "" : "s"); + else + g_snprintf(buf, sizeof buf, "%s has %d new personal message%s on Yahoo Mail.", + gc->username, pkt->mail_status, + pkt->mail_status == 1 ? "" : "s"); + do_error_dialog(buf, "New Mail!"); + } +} + +static void yahoo_callback(gpointer data, gint source, GdkInputCondition condition) { + struct gaim_connection *gc = (struct gaim_connection *)data; + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + struct yahoo_rawpacket *rawpkt; + struct yahoo_packet *pkt; + + if (!yahoo_getdata(yd->ctxt)) { + signoff(gc); + } + + while ((rawpkt = yahoo_getpacket(yd->ctxt)) != NULL) { + pkt = yahoo_parsepacket(yd->ctxt, rawpkt); + + switch (pkt->service) { + case YAHOO_SERVICE_USERSTAT: + case YAHOO_SERVICE_CHATLOGON: + case YAHOO_SERVICE_CHATLOGOFF: + case YAHOO_SERVICE_LOGON: + case YAHOO_SERVICE_LOGOFF: + case YAHOO_SERVICE_ISAWAY: + case YAHOO_SERVICE_ISBACK: + process_packet_status(gc, pkt); + break; + case YAHOO_SERVICE_MESSAGE: + case YAHOO_SERVICE_CHATMSG: + case YAHOO_SERVICE_SYSMESSAGE: + process_packet_message(gc, pkt); + break; + case YAHOO_SERVICE_CONFINVITE: + process_packet_conf_invite(gc, pkt); + break; + case YAHOO_SERVICE_CONFADDINVITE: + process_packet_conf_add_invite(gc, pkt); + break; + case YAHOO_SERVICE_CONFMSG: + process_packet_conf_msg(gc, pkt); + break; + case YAHOO_SERVICE_CONFLOGON: + process_packet_conf_logon(gc, pkt); + break; + case YAHOO_SERVICE_CONFLOGOFF: + process_packet_conf_logoff(gc, pkt); + break; + case YAHOO_SERVICE_NEWMAIL: + case YAHOO_SERVICE_NEWPERSONALMAIL: + process_packet_newmail(gc, pkt); + break; + default: + debug_printf("Unhandled packet type %s\n", + yahoo_get_service_string(pkt->service)); + break; + } + yahoo_free_packet(pkt); + yahoo_free_rawpacket(rawpkt); + } +} + +static void yahoo_login(struct aim_user *user) { + struct gaim_connection *gc = new_gaim_conn(PROTO_YAHOO, user->username, user->password); + struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); + int i; + + struct yahoo_options opt; + struct yahoo_context *ctxt; + opt.connect_mode = YAHOO_CONNECT_NORMAL; + opt.proxy_host = NULL; + ctxt = yahoo_init(user->username, user->password, &opt); + yd->ctxt = ctxt; + + set_login_progress(gc, 1, "Connecting"); + while (gtk_events_pending()) + gtk_main_iteration(); + + if (!ctxt || !yahoo_connect(ctxt)) { + debug_printf("Yahoo: Unable to connect\n"); + hide_login_progress(gc, "Unable to connect"); + destroy_gaim_conn(gc); + return; + } + + debug_printf("Yahoo: connected\n"); + + set_login_progress(gc, 3, "Getting Config"); + while (gtk_events_pending()) + gtk_main_iteration(); + + yahoo_get_config(ctxt); + + if (yahoo_cmd_logon(ctxt, YAHOO_STATUS_AVAILABLE)) { + debug_printf("Yahoo: Unable to login\n"); + hide_login_progress(gc, "Unable to login"); + destroy_gaim_conn(gc); + return; + } + + if (ctxt->buddies) { + struct yahoo_buddy **buddies; + + for (buddies = ctxt->buddies; *buddies; buddies++) { + struct yahoo_buddy *bud = *buddies; + struct buddy *b; + struct group *g; + + b = find_buddy(gc, bud->id); + if (!b) add_buddy(gc, bud->group, bud->id, bud->id); + } + } + + debug_printf("Yahoo: logged in %s\n", gc->username); + account_online(user, gc); + serv_finish_login(gc); + + gc->inpa = gdk_input_add(ctxt->sockfd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, + yahoo_callback, gc); +} + +static void yahoo_close(struct gaim_connection *gc) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + if (gc->inpa) + gdk_input_remove(gc->inpa); + gc->inpa = -1; + yahoo_cmd_logoff(yd->ctxt); + g_free(yd); +} + +static void yahoo_send_im(struct gaim_connection *gc, char *who, char *message, int away) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + yahoo_cmd_msg(yd->ctxt, gc->username, who, message); +} + +static void yahoo_set_idle(struct gaim_connection *gc, int idle) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + if (idle) + yahoo_cmd_set_away_mode(yd->ctxt, YAHOO_STATUS_IDLE, NULL); + else + yahoo_cmd_set_back_mode(yd->ctxt, YAHOO_STATUS_AVAILABLE, NULL); +} + +static void yahoo_keepalive(struct gaim_connection *gc) { + yahoo_cmd_ping(((struct yahoo_data *)gc->proto_data)->ctxt); +} + +static void gyahoo_add_buddy(struct gaim_connection *gc, char *name) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_buddy *tmpbuddy; + struct group *g = find_group_by_buddy(gc, name); + char *group = NULL; + + if (g) { + group = g->name; + } else if (yd->ctxt && yd->ctxt->buddies[0]) { + tmpbuddy = yd->ctxt->buddies[0]; + group = tmpbuddy->group; + } + + if (group) + yahoo_add_buddy(yd->ctxt, name, gc->username, group, ""); +} + +static struct prpl *my_protocol = NULL; + +void Yahoo_init(struct prpl *ret) { + /* the NULL's aren't required but they're nice to have */ + ret->protocol = PROTO_YAHOO; + ret->name = yahoo_name; + ret->list_icon = NULL; + ret->action_menu = NULL; + ret->login = yahoo_login; + ret->close = yahoo_close; + ret->send_im = yahoo_send_im; + ret->set_info = NULL; + ret->get_info = NULL; + ret->set_away = NULL; + ret->get_away_msg = NULL; + ret->set_dir = NULL; + ret->get_dir = NULL; + ret->dir_search = NULL; + ret->set_idle = yahoo_set_idle; + ret->change_passwd = NULL; + ret->add_buddy = gyahoo_add_buddy; + ret->add_buddies = NULL; + ret->remove_buddy = NULL; + ret->add_permit = NULL; + ret->add_deny = NULL; + ret->rem_permit = NULL; + ret->rem_deny = NULL; + ret->set_permit_deny = NULL; + ret->warn = NULL; + ret->accept_chat = NULL; + ret->join_chat = NULL; + ret->chat_invite = NULL; + ret->chat_leave = NULL; + ret->chat_whisper = NULL; + ret->chat_send = NULL; + ret->keepalive = yahoo_keepalive; + + my_protocol = ret; +} + +char *gaim_plugin_init(GModule *handle) { + load_protocol(Yahoo_init); + return NULL; +} + +void gaim_plugin_remove() { + struct prpl *p = find_prpl(PROTO_YAHOO); + if (p == my_protocol) + unload_protocol(p); +}