Yattm - unified GTK instant-messaging client logo
   [Generated for version 0.2-17 - Mon Jan 6 19:01:23 GMT+1 2003]

Home - Main Page - Data Structures - File List - Data Fields - Globals

message_parse.c

Go to the documentation of this file.
00001 /*
00002  * Yattm 
00003  *
00004  * Copyright (C) 1999, Torrey Searle <tsearle@uci.edu>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 /****************************
00023   Message Parser
00024   ***************************/
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include "intl.h"
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <errno.h>
00034 #include <sys/time.h>
00035 
00036 #ifdef __MINGW32__
00037 #include <winsock2.h>
00038 #else
00039 #include <sys/wait.h>
00040 #include <sys/socket.h>
00041 #include <netinet/in.h>
00042 #include <arpa/inet.h>
00043 #include <netdb.h>
00044 #include <pthread.h>
00045 #endif
00046 
00047 #include <sys/stat.h>
00048 #include <stdlib.h>
00049 #include <signal.h>
00050 
00051 #include "chat_window.h"
00052 #include "message_parse.h"
00053 #include "util.h"
00054 #include "dialog.h"
00055 #include "globals.h"
00056 #include "progress_window.h"
00057 
00058 
00059 char filename[1024];
00060 // static unsigned long filename_len = 0; // unused
00061 static int xfer_in_progress = 0;
00062 static FILE * fp;
00063 static unsigned long amount_recieved;
00064 static int fd;
00065 #ifndef __MINGW32__
00066 static pthread_mutex_t mutex;
00067 #endif
00068 
00069 typedef struct _send_file_struct
00070 {
00071     char filename[1024];
00072     int s;
00073 } send_file_struct;
00074 
00075 typedef struct {
00076     int timer;
00077     int input;
00078     int tag;
00079 } progress_callback_data;
00080 
00081 
00082 void send_file2(void * ptr )
00083 {
00084     send_file_struct * sfs = ptr;
00085     unsigned long i = 0;
00086     char buff[1025];
00087 
00088 
00089 #ifndef __MINGW32__
00090     pthread_mutex_lock(&mutex);
00091     xfer_in_progress = 1;
00092     pthread_mutex_unlock(&mutex);
00093     signal(SIGPIPE,SIG_IGN);
00094 
00095 
00096 
00097     if(!fp)
00098     {
00099         close(sfs->s);
00100         pthread_mutex_lock(&mutex);
00101         xfer_in_progress = -2;
00102         pthread_mutex_unlock(&mutex);
00103         signal(SIGPIPE,SIG_DFL);
00104         pthread_mutex_destroy(&mutex);
00105         pthread_exit(0);
00106     }
00107     i = 0;
00108     while(!feof(fp))
00109     {
00110         buff[i%1024] = fgetc(fp);
00111         buff[i%1024+1] = 0;
00112 
00113         if(++i % 1024 == 0 )
00114         {
00115                 int j = write(sfs->s, buff,1024);
00116                 if( j < 0 )
00117                 {
00118                     signal(SIGPIPE,SIG_DFL);
00119                     fclose(fp);
00120                     close(sfs->s);
00121                     pthread_mutex_lock(&mutex);
00122                     xfer_in_progress = -1;
00123                     pthread_mutex_unlock(&mutex);
00124                     pthread_mutex_destroy(&mutex);
00125                     pthread_exit(0);
00126                 }
00127                 while(j < 1024 )
00128                 {
00129                     int k = send(sfs->s, j+buff, 1024-j,0);
00130                     if(k < 0 )
00131                     {
00132                         signal(SIGPIPE,SIG_DFL);
00133                         pthread_mutex_lock(&mutex);
00134                         xfer_in_progress = -1;
00135                         pthread_mutex_unlock(&mutex);
00136                         fclose(fp);
00137                         close(sfs->s);
00138                         pthread_mutex_destroy(&mutex);
00139                         pthread_exit(0);
00140                     }
00141 
00142                     j += k;
00143                 }
00144                 pthread_mutex_lock(&mutex);
00145                 amount_recieved = i;
00146                 pthread_mutex_unlock(&mutex);
00147         }
00148     }
00149 
00150     if( (i-1)%1024 != 0 )
00151     {
00152         write(sfs->s, buff, (i-1)%1024);
00153     }
00154 
00155     signal(SIGPIPE,SIG_DFL);
00156 
00157     pthread_mutex_lock(&mutex);
00158     xfer_in_progress = 0;
00159     pthread_mutex_unlock(&mutex);
00160     fclose(fp);
00161     close(sfs->s);
00162     pthread_mutex_destroy(&mutex);
00163     pthread_exit(0);
00164 #endif
00165 }
00166         
00167 int update_send_progress(gpointer data )
00168 {
00169     progress_callback_data * pcd = data;
00170 #ifndef __MINGW32__
00171     pthread_mutex_lock(&mutex);
00172 #endif
00173     if( xfer_in_progress > 0 )
00174     {
00175         update_progress(pcd->tag, amount_recieved);
00176     }
00177     else if( xfer_in_progress == -1 )
00178     {
00179         do_error_dialog(_("Remote Side Disconnected"), _("Yattm file x-fer"));
00180         progress_window_close(pcd->tag);
00181         gtk_timeout_remove(pcd->timer);
00182         g_free(pcd);
00183     }
00184     else if( xfer_in_progress == -2 )
00185     {
00186         do_error_dialog(_("Unable to open file!"), _("Yattm file x-fer"));
00187         progress_window_close(pcd->tag);
00188         gtk_timeout_remove(pcd->timer);
00189         g_free(pcd);
00190     }
00191     else
00192     {
00193         do_error_dialog(_("File Sent Successfully"), _("Yattm file x-fer"));
00194         progress_window_close(pcd->tag);
00195         gtk_timeout_remove(pcd->timer);
00196         g_free(pcd);
00197     }
00198 #ifndef __MINGW32__
00199     pthread_mutex_unlock(&mutex);
00200 #endif
00201     return TRUE;
00202 }
00203 
00204 void send_file( char * filename, int s )
00205 {
00206     static send_file_struct sfs;
00207     struct stat fileinfo;
00208 #ifndef __MINGW32__
00209     static pthread_t thread;
00210 #endif
00211     int i;
00212     char buff[6];
00213     unsigned long filelen;
00214 //  struct timeval tv;
00215     char accept[10] = "";
00216 //  fd_set set;
00217 
00218     if(xfer_in_progress)
00219         return;
00220 
00221 
00222     strncpy(sfs.filename, filename,1024);
00223     sfs.s = s;
00224     stat( sfs.filename, &fileinfo);
00225 
00226     for( i = strlen(filename); i >=0; i-- )
00227     {
00228         if(filename[i]=='/')
00229         {
00230             break;
00231         }
00232     }
00233     g_snprintf(buff, 1025, "%05d", strlen(filename+i+1));
00234     write(s,buff,5);
00235     write(s,filename+i+1,strlen(filename+i+1));
00236     filelen = htonl(fileinfo.st_size);
00237     write(s,&filelen,4);
00238 
00239     /*
00240     FD_ZERO(&set);
00241     FD_SET(s, &set);
00242 
00243     tv.tv_sec = 0;
00244     tv.tv_usec = 20;
00245 
00246     while(!select( s+1, &set, NULL, NULL, &tv ) )
00247     {
00248          while (gtk_events_pending())
00249                 gtk_main_iteration();
00250     }
00251 */
00252     read( s, accept, 10);
00253 
00254     if(!strcmp(accept,"ACCEPT") )
00255     {
00256         progress_callback_data * pcd = g_new0(progress_callback_data, 1);
00257         xfer_in_progress = 1;
00258         fp = fopen(filename,"rb");
00259         printf("%s %s %d %5d %p\n", filename, filename+i+1, strlen(filename), htons(strlen(filename+i+1)), fp);
00260         pcd->tag = progress_window_new(filename,fileinfo.st_size);
00261 #ifndef __MINGW32__
00262         pthread_mutex_init(&mutex, NULL);
00263         if(pthread_create(&thread, NULL, 
00264                     (void*)&send_file2, (void*)&sfs ))
00265             exit(1);
00266 #else
00267         send_file2(&sfs);
00268 #endif
00269         pcd->timer = gtk_timeout_add((guint32)500, update_send_progress, pcd);
00270     }
00271     else
00272     {
00273         do_error_dialog(_("Remote Side has aborted the\nfile transfer"),
00274                         _("Yattm File Transfer"));
00275     }
00276 
00277 }
00278 
00279 
00280 
00281 void get_file2( gpointer data, gint source, GdkInputCondition condition )
00282 {
00283     char buffer[1025];
00284     int len2;
00285     progress_callback_data *pcd = data;
00286 
00287     if(!(len2 = recv(source, buffer, 1024, 0)))
00288     {
00289         fclose(fp);
00290         close(source);
00291         do_error_dialog(_("File Receive Complete"), _("Yattm File x-fer"));
00292         progress_window_close(pcd->tag);
00293 
00294         xfer_in_progress = 0;
00295         gdk_input_remove(pcd->input);
00296         g_free(pcd);
00297     }
00298     else
00299     {
00300         int i;
00301         for(i=0; i <len2; i++)
00302         {
00303             fputc(buffer[i], fp);
00304         }
00305         amount_recieved += len2;
00306         update_progress(pcd->tag, amount_recieved);
00307     }
00308 }
00309 
00310     
00311 void accept_file( GtkWidget * widget, gpointer data )
00312 {
00313     int result = (int)gtk_object_get_user_data( GTK_OBJECT(widget));
00314     progress_callback_data * pcd = data;
00315     if(result)
00316     {
00317         char val[10] = "ACCEPT";
00318         printf("write: %d\n", write(fd, val, 10));
00319 #ifndef __MINGW32__
00320         fsync(fd);
00321 #endif
00322         pcd->input = gdk_input_add(fd, GDK_INPUT_READ, get_file2, pcd); 
00323     }
00324     else
00325     {
00326         char val[10] = "DENY";
00327         write(fd, val, 10);
00328         close(fd);
00329         fclose(fp);
00330         xfer_in_progress = 0;
00331         progress_window_close(pcd->tag);
00332         g_free(pcd);
00333     }
00334 }
00335 
00336 void get_file( int s )
00337 {
00338     int len;
00339     unsigned long filelen;
00340     struct timeval tv;
00341     char buffer2[1024];
00342     char buffer[1024];
00343     char buffer3[1024];
00344     progress_callback_data *pcd = g_new0(progress_callback_data, 1);
00345     fd_set set;
00346 
00347     fd = accept(s, NULL, NULL );
00348     close(s);
00349     if(xfer_in_progress)
00350         return;
00351     xfer_in_progress = 1;
00352 
00353     FD_ZERO(&set);
00354     FD_SET(fd, &set);
00355 
00356     tv.tv_sec = 0;
00357     tv.tv_usec = 20;
00358 
00359     while(!select( fd+1, &set, NULL, NULL, &tv ) )
00360     {
00361          while (gtk_events_pending())
00362                 gtk_main_iteration();
00363     }
00364 
00365     recv(fd, buffer, 5, 0);
00366     buffer[5] = 0;
00367     len = atoi(buffer);
00368     recv(fd, buffer2, len, 0);
00369     buffer2[len]=0;
00370     recv(fd, &filelen, 4, 0);
00371     filelen = ntohl(filelen);
00372 
00373     pcd->tag = progress_window_new(buffer2, filelen);
00374 
00375     g_snprintf( buffer, 1024, "%s/%s", getenv("HOME"),buffer2);
00376     printf("receiving file %s\n", buffer);
00377     amount_recieved = 0;
00378     fp = fopen(buffer, "wb");
00379 
00380     g_snprintf( buffer3, 1024, _("Would you like to accept\n the file %s?\nSize=%lu"), buffer2,(unsigned long)filelen);
00381     do_dialog( buffer3, _("Download File"), accept_file, pcd );
00382 }
00383 
00384 
00385 void eb_parse_incomming_message( eb_local_account * account,
00386                  eb_account * remote,
00387                                  struct service * serv,
00388                  gchar * message )
00389 {
00390     char * buff;
00391     char * ptr;
00392     buff = strdup(message);
00393 
00394     ptr = strtok(buff," ");
00395 
00396     if(ptr && !strcmp(ptr, "EB_COMMAND") && !xfer_in_progress)
00397     {
00398         eb_debug(DBG_CORE, "EB_COMMAND received\n");
00399         ptr = strtok(NULL, " ");
00400         if(ptr && !strcmp(ptr, "SEND_FILE"))
00401         {
00402             char buff2[1024];
00403             char   myname[1024];
00404             int    s;
00405             struct sockaddr_in sa;
00406             struct hostent *hp;
00407 
00408             memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
00409             gethostname(myname, 1023);           /* who are we? */
00410             hp= gethostbyname(myname);                  /* get our address info */
00411             if (hp == NULL) {                            /* we don't exist !? */
00412                 eb_debug(DBG_CORE, "gethostbyname failed: %s\n", strerror(errno));
00413                 free(buff);
00414                     return;
00415             }
00416             sa.sin_family= hp->h_addrtype;              /* this is our host address */
00417             sa.sin_port= htons(45678);                  /* this is our port number */
00418             if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* create socket */
00419                 eb_debug(DBG_CORE, "socket failed: %s\n", strerror(errno));
00420                 free(buff);
00421                     return;
00422             }
00423             if (bind(s,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)) < 0) {
00424                 eb_debug(DBG_CORE, "bind failed: %s\n", strerror(errno));
00425                     close(s);
00426                 free(buff);
00427                 return;                               /* bind address to socket */
00428             }
00429             listen(s, 1);                               /* max # of queued connects */
00430             g_snprintf(buff2,1024,"EB_COMMAND ACCEPT %s", get_local_addresses());
00431             RUN_SERVICE(remote)->send_im(account,remote, buff2);
00432             get_file(s);
00433         }
00434         if(ptr && !strcmp(ptr, "ACCEPT"))
00435         {
00436             int sockfd;
00437             struct sockaddr_in dest_addr;
00438 
00439             ptr = strtok(NULL, " ");
00440             if(!ptr)
00441             {
00442                 free(buff);
00443                 return;
00444             }
00445 
00446             sockfd = socket(AF_INET, SOCK_STREAM, 0);
00447 
00448             dest_addr.sin_family = AF_INET;
00449             dest_addr.sin_port = htons(45678);
00450             dest_addr.sin_addr.s_addr = inet_addr(ptr);
00451             memset(&(dest_addr.sin_zero), 0, 8);
00452 
00453             connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
00454             send_file(filename, sockfd);
00455         }
00456     }
00457     else
00458     {
00459         gchar * message2 = linkify(message);
00460         eb_chat_window_display_remote_message( account, remote, serv, message2 );
00461         g_free(message2);
00462     }
00463     free(buff);
00464 }
00465 
00466 void eb_update_status( eb_account * remote,
00467                        gchar * message )
00468 {
00469         eb_chat_window_display_status( remote, message );
00470 }

Contact: Andy Maloney     [Documentation generated by doxygen]