/[weechat]/weechat/src/irc/irc-dcc.c
ViewVC logotype

Diff of /weechat/src/irc/irc-dcc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.20 by flashcode, Tue Jul 12 19:28:09 2005 UTC revision 1.21 by flashcode, Wed Jul 13 16:24:47 2005 UTC
# Line 64  dcc_redraw (int highlight) Line 64  dcc_redraw (int highlight)
64  }  }
65    
66  /*  /*
67     * dcc_search: search a DCC
68     */
69    
70    t_irc_dcc *
71    dcc_search (t_irc_server *server, int type, int status, int port)
72    {
73        t_irc_dcc *ptr_dcc;
74        
75        for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
76        {
77            if ((ptr_dcc->server == server)
78                && (ptr_dcc->type == type)
79                && (ptr_dcc->status = status)
80                && (ptr_dcc->port == port))
81                return ptr_dcc;
82        }
83        
84        /* DCC not found */
85        return NULL;
86    }
87    
88    /*
89     * dcc_file_is_resumable: check if a file can be used for resuming a download
90     */
91    
92    int
93    dcc_file_is_resumable (t_irc_dcc *ptr_dcc, char *filename)
94    {
95        struct stat st;
96        
97        if (access (filename, W_OK) == 0)
98        {
99            if (stat (filename, &st) != -1)
100            {
101                if ((unsigned long) st.st_size < ptr_dcc->size)
102                {
103                    ptr_dcc->start_resume = (unsigned long) st.st_size;
104                    ptr_dcc->pos = st.st_size;
105                    ptr_dcc->last_check_pos = st.st_size;
106                    return 1;
107                }
108            }
109        }
110        
111        /* not resumable */
112        return 0;
113    }
114    
115    /*
116     * dcc_find_filename: find local filename for a DCC
117     *                    if type if file/recv, add a suffix (like .1) if needed
118     *                    if download is resumable, set "start_resume" to good value
119     */
120    
121    void
122    dcc_find_filename (t_irc_dcc *ptr_dcc)
123    {
124        char *ptr_home, *filename2;
125        
126        ptr_home = getenv ("HOME");
127        ptr_dcc->local_filename = (char *) malloc (strlen (cfg_dcc_download_path) +
128                                                   strlen (ptr_dcc->nick) +
129                                                   strlen (ptr_dcc->filename) +
130                                                   ((cfg_dcc_download_path[0] == '~') ?
131                                                    strlen (ptr_home) : 0) +
132                                                   4);
133        if (!ptr_dcc->local_filename)
134            return;
135        
136        if (cfg_dcc_download_path[0] == '~')
137        {
138            strcpy (ptr_dcc->local_filename, ptr_home);
139            strcat (ptr_dcc->local_filename, cfg_dcc_download_path + 1);
140        }
141        else
142            strcpy (ptr_dcc->local_filename, cfg_dcc_download_path);
143        if (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != DIR_SEPARATOR_CHAR)
144            strcat (ptr_dcc->local_filename, DIR_SEPARATOR);
145        strcat (ptr_dcc->local_filename, ptr_dcc->nick);
146        strcat (ptr_dcc->local_filename, ".");
147        strcat (ptr_dcc->local_filename, ptr_dcc->filename);
148        
149        /* file already exists? */
150        if (access (ptr_dcc->local_filename, F_OK) == 0)
151        {
152            if (dcc_file_is_resumable (ptr_dcc, ptr_dcc->local_filename))
153                return;
154            
155            /* if auto rename is not set, then abort DCC */
156            if (!cfg_dcc_auto_rename)
157            {
158                dcc_close (ptr_dcc, DCC_FAILED);
159                dcc_redraw (1);
160                return;
161            }
162            
163            filename2 = (char *) malloc (strlen (ptr_dcc->local_filename) + 16);
164            if (!filename2)
165            {
166                dcc_close (ptr_dcc, DCC_FAILED);
167                dcc_redraw (1);
168                return;
169            }
170            ptr_dcc->filename_suffix = 0;
171            do
172            {
173                ptr_dcc->filename_suffix++;
174                sprintf (filename2, "%s.%d",
175                         ptr_dcc->local_filename,
176                         ptr_dcc->filename_suffix);
177                if (access (filename2, F_OK) == 0)
178                {
179                    if (dcc_file_is_resumable (ptr_dcc, filename2))
180                        break;
181                }
182                else
183                    break;
184            }
185            while (1);
186            
187            free (ptr_dcc->local_filename);
188            ptr_dcc->local_filename = strdup (filename2);
189            free (filename2);
190        }
191    }
192    
193    /*
194   * dcc_calculate_speed: calculate DCC speed (for files only)   * dcc_calculate_speed: calculate DCC speed (for files only)
195   */   */
196    
# Line 81  dcc_calculate_speed (t_irc_dcc *ptr_dcc, Line 208  dcc_calculate_speed (t_irc_dcc *ptr_dcc,
208              elapsed = local_time - ptr_dcc->start_transfer;              elapsed = local_time - ptr_dcc->start_transfer;
209              if (elapsed == 0)              if (elapsed == 0)
210                  elapsed = 1;                  elapsed = 1;
211              ptr_dcc->bytes_per_sec = ptr_dcc->pos / elapsed;              ptr_dcc->bytes_per_sec = (ptr_dcc->pos - ptr_dcc->start_resume) / elapsed;
212          }          }
213          else          else
214          {          {
# Line 199  dcc_close (t_irc_dcc *ptr_dcc, int statu Line 326  dcc_close (t_irc_dcc *ptr_dcc, int statu
326                                    COLOR_WIN_CHAT_CHANNEL,                                    COLOR_WIN_CHAT_CHANNEL,
327                                    "%s",                                    "%s",
328                                    ptr_dcc->local_filename);                                    ptr_dcc->local_filename);
329                  gui_printf (ptr_dcc->server->buffer, ") ");                  gui_printf (ptr_dcc->server->buffer, ")");
330              }              }
331              if (ptr_dcc->type == DCC_FILE_SEND)              if (ptr_dcc->type == DCC_FILE_SEND)
332                  gui_printf (ptr_dcc->server->buffer, _(" sent to "));                  gui_printf (ptr_dcc->server->buffer, _(" sent to "));
# Line 294  dcc_channel_for_chat (t_irc_dcc *ptr_dcc Line 421  dcc_channel_for_chat (t_irc_dcc *ptr_dcc
421  }  }
422    
423  /*  /*
424   * dcc_accept: accepts a DCC file or chat request   * dcc_recv_connect_init: connect to sender and init file or chat
425   */   */
426    
427  void  void
428  dcc_accept (t_irc_dcc *ptr_dcc)  dcc_recv_connect_init (t_irc_dcc *ptr_dcc)
429  {  {
     char *ptr_home, *filename2;  
       
430      if (!dcc_connect (ptr_dcc))      if (!dcc_connect (ptr_dcc))
431      {      {
432          dcc_close (ptr_dcc, DCC_FAILED);          dcc_close (ptr_dcc, DCC_FAILED);
# Line 314  dcc_accept (t_irc_dcc *ptr_dcc) Line 439  dcc_accept (t_irc_dcc *ptr_dcc)
439          /* DCC file => look for local filename and open it in writing mode */          /* DCC file => look for local filename and open it in writing mode */
440          if (DCC_IS_FILE(ptr_dcc->type))          if (DCC_IS_FILE(ptr_dcc->type))
441          {          {
442              ptr_home = getenv ("HOME");              if (ptr_dcc->start_resume > 0)
443              ptr_dcc->local_filename = (char *) malloc (strlen (cfg_dcc_download_path) +                  ptr_dcc->file = open (ptr_dcc->local_filename,
444                                                         strlen (ptr_dcc->nick) +                                        O_APPEND | O_WRONLY | O_NONBLOCK);
                                                        strlen (ptr_dcc->filename) +  
                                                        ((cfg_dcc_download_path[0] == '~') ?  
                                                            strlen (ptr_home) : 0) +  
                                                        4);  
             if (!ptr_dcc->local_filename)  
             {  
                 dcc_close (ptr_dcc, DCC_FAILED);  
                 dcc_redraw (1);  
                 return;  
             }  
             if (cfg_dcc_download_path[0] == '~')  
             {  
                 strcpy (ptr_dcc->local_filename, ptr_home);  
                 strcat (ptr_dcc->local_filename, cfg_dcc_download_path + 1);  
             }  
445              else              else
446                  strcpy (ptr_dcc->local_filename, cfg_dcc_download_path);                  ptr_dcc->file = open (ptr_dcc->local_filename,
447              if (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != DIR_SEPARATOR_CHAR)                                        O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
448                  strcat (ptr_dcc->local_filename, DIR_SEPARATOR);                                        0644);
             strcat (ptr_dcc->local_filename, ptr_dcc->nick);  
             strcat (ptr_dcc->local_filename, ".");  
             strcat (ptr_dcc->local_filename, ptr_dcc->filename);  
               
             /* file already exists? */  
             if (access (ptr_dcc->local_filename, F_OK) == 0)  
             {  
                 /* if auto rename is not set, then abort DCC */  
                 if (!cfg_dcc_auto_rename)  
                 {  
                     dcc_close (ptr_dcc, DCC_FAILED);  
                     dcc_redraw (1);  
                     return;  
                 }  
                   
                 filename2 = (char *) malloc (strlen (ptr_dcc->local_filename) + 16);  
                 if (!filename2)  
                 {  
                     dcc_close (ptr_dcc, DCC_FAILED);  
                     dcc_redraw (1);  
                     return;  
                 }  
                 ptr_dcc->filename_suffix = 0;  
                 do  
                 {  
                     ptr_dcc->filename_suffix++;  
                     sprintf (filename2, "%s.%d",  
                              ptr_dcc->local_filename,  
                              ptr_dcc->filename_suffix);  
                 }  
                 while (access (filename2, F_OK) == 0);  
                   
                 free (ptr_dcc->local_filename);  
                 ptr_dcc->local_filename = strdup (filename2);  
                 free (filename2);  
             }  
             ptr_dcc->file = open (ptr_dcc->local_filename,  
                                   O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,  
                                   0644);  
449              ptr_dcc->start_transfer = time (NULL);              ptr_dcc->start_transfer = time (NULL);
450                ptr_dcc->last_check_time = time (NULL);
451          }          }
452          else          else
453          {          {
# Line 387  dcc_accept (t_irc_dcc *ptr_dcc) Line 459  dcc_accept (t_irc_dcc *ptr_dcc)
459  }  }
460    
461  /*  /*
462     * dcc_accept: accepts a DCC file or chat request
463     */
464    
465    void
466    dcc_accept (t_irc_dcc *ptr_dcc)
467    {
468        if (DCC_IS_FILE(ptr_dcc->type) && (ptr_dcc->start_resume > 0))
469        {
470            ptr_dcc->status = DCC_CONNECTING;
471            server_sendf (ptr_dcc->server,
472                          (strchr (ptr_dcc->filename, ' ')) ?
473                              "PRIVMSG %s :\01DCC RESUME \"%s\" %d %u\01\r\n" :
474                              "PRIVMSG %s :\01DCC RESUME %s %d %u\01\r\n",
475                          ptr_dcc->nick, ptr_dcc->filename,
476                          ptr_dcc->port, ptr_dcc->start_resume);
477            dcc_redraw (1);
478        }
479        else
480            dcc_recv_connect_init (ptr_dcc);
481    }
482    
483    /*
484     * dcc_accept_resume: accepts a resume and inform the receiver
485     */
486    
487    void
488    dcc_accept_resume (t_irc_server *server, char *filename, int port,
489                       unsigned long pos_start)
490    {
491        t_irc_dcc *ptr_dcc;
492        
493        ptr_dcc = dcc_search (server, DCC_FILE_SEND, DCC_CONNECTING, port);
494        if (ptr_dcc)
495        {
496            ptr_dcc->pos = pos_start;
497            ptr_dcc->ack = pos_start;
498            ptr_dcc->start_resume = pos_start;
499            ptr_dcc->last_check_pos = pos_start;
500            server_sendf (ptr_dcc->server,
501                          (strchr (ptr_dcc->filename, ' ')) ?
502                              "PRIVMSG %s :\01DCC ACCEPT \"%s\" %d %u\01\r\n" :
503                              "PRIVMSG %s :\01DCC ACCEPT %s %d %u\01\r\n",
504                          ptr_dcc->nick, ptr_dcc->filename,
505                          ptr_dcc->port, ptr_dcc->start_resume);
506            
507            irc_display_prefix (ptr_dcc->server->buffer, PREFIX_INFO);
508            gui_printf (ptr_dcc->server->buffer, _("DCC: file "));
509            gui_printf_color (ptr_dcc->server->buffer,
510                              COLOR_WIN_CHAT_CHANNEL,
511                              "%s ",
512                              ptr_dcc->filename);
513            gui_printf (ptr_dcc->server->buffer, _("resumed at position %u\n"),
514                        ptr_dcc->start_resume);
515            dcc_redraw (1);
516        }
517        else
518            gui_printf (server->buffer,
519                        _("%s can't resume file \"%s\" (port: %d, start position: %u): DCC not found or ended\n"),
520                        WEECHAT_ERROR, filename, port, pos_start);
521    }
522    
523    /*
524     * dcc_start_resume: called when "DCC ACCEPT" is received (resume accepted by sender)
525     */
526    
527    void
528    dcc_start_resume (t_irc_server *server, char *filename, int port,
529                      unsigned long pos_start)
530    {
531        t_irc_dcc *ptr_dcc;
532        
533        ptr_dcc = dcc_search (server, DCC_FILE_RECV, DCC_CONNECTING, port);
534        if (ptr_dcc)
535        {
536            ptr_dcc->pos = pos_start;
537            ptr_dcc->ack = pos_start;
538            ptr_dcc->start_resume = pos_start;
539            ptr_dcc->last_check_pos = pos_start;
540            dcc_recv_connect_init (ptr_dcc);
541        }
542        else
543            gui_printf (server->buffer,
544                        _("%s can't resume file \"%s\" (port: %d, start position: %u): DCC not found or ended\n"),
545                        WEECHAT_ERROR, filename, port, pos_start);
546    }
547    
548    /*
549   * dcc_add: add a DCC file to queue   * dcc_add: add a DCC file to queue
550   */   */
551    
# Line 423  dcc_add (t_irc_server *server, int type, Line 582  dcc_add (t_irc_server *server, int type,
582          new_dcc->filename = strdup (_("DCC chat"));          new_dcc->filename = strdup (_("DCC chat"));
583      else      else
584          new_dcc->filename = (filename) ? strdup (filename) : NULL;          new_dcc->filename = (filename) ? strdup (filename) : NULL;
585      new_dcc->local_filename = (local_filename) ? strdup (local_filename) : NULL;      new_dcc->local_filename = NULL;
586      new_dcc->filename_suffix = -1;      new_dcc->filename_suffix = -1;
587      new_dcc->size = size;      new_dcc->size = size;
588      new_dcc->pos = 0;      new_dcc->pos = 0;
589      new_dcc->ack = 0;      new_dcc->ack = 0;
590      new_dcc->last_check_time = 0;      new_dcc->start_resume = 0;
591        new_dcc->last_check_time = time (NULL);
592      new_dcc->last_check_pos = 0;      new_dcc->last_check_pos = 0;
593      new_dcc->bytes_per_sec = 0;      new_dcc->bytes_per_sec = 0;
594      new_dcc->last_activity = time (NULL);      new_dcc->last_activity = time (NULL);
595        if (local_filename)
596            new_dcc->local_filename = strdup (local_filename);
597        else
598            dcc_find_filename (new_dcc);
599      new_dcc->prev_dcc = NULL;      new_dcc->prev_dcc = NULL;
600      new_dcc->next_dcc = dcc_list;      new_dcc->next_dcc = dcc_list;
601      if (dcc_list)      if (dcc_list)
# Line 457  dcc_add (t_irc_server *server, int type, Line 621  dcc_add (t_irc_server *server, int type,
621          gui_printf (server->buffer, ", ");          gui_printf (server->buffer, ", ");
622          gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);          gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);
623          gui_printf (server->buffer, _(" bytes\n"));          gui_printf (server->buffer, _(" bytes\n"));
624            dcc_redraw (1);
625      }      }
626      if (type == DCC_FILE_SEND)      if (type == DCC_FILE_SEND)
627      {      {
# Line 470  dcc_add (t_irc_server *server, int type, Line 635  dcc_add (t_irc_server *server, int type,
635          gui_printf (server->buffer, "), ");          gui_printf (server->buffer, "), ");
636          gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);          gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);
637          gui_printf (server->buffer, _(" bytes\n"));          gui_printf (server->buffer, _(" bytes\n"));
638            dcc_redraw (1);
639      }      }
640      if (type == DCC_CHAT_RECV)      if (type == DCC_CHAT_RECV)
641      {      {
# Line 481  dcc_add (t_irc_server *server, int type, Line 647  dcc_add (t_irc_server *server, int type,
647                            "%d.%d.%d.%d",                            "%d.%d.%d.%d",
648                            addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);                            addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
649          gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, ")\n");          gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, ")\n");
650            dcc_redraw (1);
651      }      }
652      if (type == DCC_CHAT_SEND)      if (type == DCC_CHAT_SEND)
653      {      {
654          irc_display_prefix (server->buffer, PREFIX_INFO);          irc_display_prefix (server->buffer, PREFIX_INFO);
655          gui_printf (server->buffer, _("Sending DCC chat request to "));          gui_printf (server->buffer, _("Sending DCC chat request to "));
656          gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK, "%s\n", nick);          gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK, "%s\n", nick);
657            dcc_redraw (1);
658        }
659        
660        if (DCC_IS_FILE(type) && (!new_dcc->local_filename))
661        {
662            dcc_close (new_dcc, DCC_FAILED);
663            dcc_redraw (1);
664            return NULL;
665        }
666        
667        if (DCC_IS_FILE(type) && (new_dcc->start_resume > 0))
668        {
669            irc_display_prefix (new_dcc->server->buffer, PREFIX_INFO);
670            gui_printf (new_dcc->server->buffer, _("DCC: file "));
671            gui_printf_color (new_dcc->server->buffer,
672                              COLOR_WIN_CHAT_CHANNEL,
673                              "%s",
674                              new_dcc->filename);
675            gui_printf (new_dcc->server->buffer, _(" (local filename: "));
676            gui_printf_color (new_dcc->server->buffer,
677                              COLOR_WIN_CHAT_CHANNEL,
678                              "%s",
679                              new_dcc->local_filename);
680            gui_printf (new_dcc->server->buffer, ") ");
681            gui_printf (new_dcc->server->buffer, _("will be resumed at position %u\n"),
682                        new_dcc->start_resume);
683            dcc_redraw (1);
684      }      }
685            
686      /* connect if needed and redraw DCC buffer */      /* connect if needed and redraw DCC buffer */
# Line 495  dcc_add (t_irc_server *server, int type, Line 689  dcc_add (t_irc_server *server, int type,
689          if (!dcc_connect (new_dcc))          if (!dcc_connect (new_dcc))
690          {          {
691              dcc_close (new_dcc, DCC_FAILED);              dcc_close (new_dcc, DCC_FAILED);
692                dcc_redraw (1);
693              return NULL;              return NULL;
694          }          }
695      }      }
# Line 532  dcc_send_request (t_irc_server *server, Line 727  dcc_send_request (t_irc_server *server,
727      if (type == DCC_FILE_SEND)      if (type == DCC_FILE_SEND)
728      {      {
729          /* add home if filename not beginning with '/' (not for Win32) */          /* add home if filename not beginning with '/' (not for Win32) */
730          #ifdef _WIN32  #ifdef _WIN32
731          filename2 = strdup (filename);          filename2 = strdup (filename);
732          #else  #else
733          if (filename[0] == '/')          if (filename[0] == '/')
734              filename2 = strdup (filename);              filename2 = strdup (filename);
735          else          else
# Line 564  dcc_send_request (t_irc_server *server, Line 759  dcc_send_request (t_irc_server *server,
759                  strcat (filename2, DIR_SEPARATOR);                  strcat (filename2, DIR_SEPARATOR);
760              strcat (filename2, filename);              strcat (filename2, filename);
761          }          }
762          #endif  #endif
763                    
764          /* check if file exists */          /* check if file exists */
765          if (stat (filename2, &st) == -1)          if (stat (filename2, &st) == -1)
# Line 719  dcc_chat_sendf (t_irc_dcc *ptr_dcc, char Line 914  dcc_chat_sendf (t_irc_dcc *ptr_dcc, char
914      buffer[sizeof (buffer) - 1] = '\0';      buffer[sizeof (buffer) - 1] = '\0';
915      if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))      if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))
916          size_buf = strlen (buffer);          size_buf = strlen (buffer);
917      #ifdef DEBUG  #ifdef DEBUG
918      buffer[size_buf - 2] = '\0';      buffer[size_buf - 2] = '\0';
919      gui_printf (ptr_dcc->server->buffer, "[DEBUG] Sending to remote host (DCC CHAT) >>> %s\n", buffer);      gui_printf (ptr_dcc->server->buffer, "[DEBUG] Sending to remote host (DCC CHAT) >>> %s\n", buffer);
920      buffer[size_buf - 2] = '\r';      buffer[size_buf - 2] = '\r';
921      #endif  #endif
922      buf2 = weechat_convert_encoding ((cfg_look_charset_internal && cfg_look_charset_internal[0]) ?      buf2 = weechat_convert_encoding ((cfg_look_charset_internal && cfg_look_charset_internal[0]) ?
923                                       cfg_look_charset_internal : local_charset,                                       cfg_look_charset_internal : local_charset,
924                                       cfg_look_charset_encode,                                       cfg_look_charset_encode,

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26