00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00215 char accept[10] = "";
00216
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
00241
00242
00243
00244
00245
00246
00247
00248
00249
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));
00409 gethostname(myname, 1023);
00410 hp= gethostbyname(myname);
00411 if (hp == NULL) {
00412 eb_debug(DBG_CORE, "gethostbyname failed: %s\n", strerror(errno));
00413 free(buff);
00414 return;
00415 }
00416 sa.sin_family= hp->h_addrtype;
00417 sa.sin_port= htons(45678);
00418 if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) {
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;
00428 }
00429 listen(s, 1);
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 }