Mercurial > pidgin
annotate src/protocols/icq/filesession.c @ 4891:cfa045006bec
[gaim-migrate @ 5221]
this saves the blist.xml file to an alternate name, and then moves it, that
way we don't lose your precious buddies if gaim crashes.
Of course, if gaim were to crash, it wouldn't be gaim's fault, it would be
the fault of some external force. This is because gaim is perfect, and
Sean is perfect. Yeah.
This should be done for .gaimrc too, but i'm too tired to do that right now.
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Tue, 25 Mar 2003 06:35:45 +0000 |
| parents | f0a2a9afdb77 |
| children |
| rev | line source |
|---|---|
| 2086 | 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 | |
| 3 /* | |
|
2496
f0a2a9afdb77
[gaim-migrate @ 2509]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
4 * $Id: filesession.c 2509 2001-10-13 00:06:18Z warmenhoven $ |
| 2086 | 5 * |
| 6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and | |
| 7 * Bill Soudan <soudan@kde.org> | |
| 8 * | |
| 9 * This program is free software; you can redistribute it and/or modify | |
| 10 * it under the terms of the GNU General Public License as published by | |
| 11 * the Free Software Foundation; either version 2 of the License, or | |
| 12 * (at your option) any later version. | |
| 13 * | |
| 14 * This program is distributed in the hope that it will be useful, | |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 * GNU General Public License for more details. | |
| 18 * | |
| 19 * You should have received a copy of the GNU General Public License | |
| 20 * along with this program; if not, write to the Free Software | |
| 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 22 * | |
| 23 */ | |
| 24 | |
| 25 #include <stdlib.h> | |
| 26 #include <fcntl.h> | |
| 27 #include <sys/stat.h> | |
| 28 | |
| 29 #ifdef _MSVC_ | |
| 30 #include <io.h> | |
| 31 #define open _open | |
| 32 #define close _close | |
| 33 #define read _read | |
| 34 #define write _write | |
| 35 #endif | |
| 36 | |
| 37 #include "icqlib.h" | |
| 38 #include "filesession.h" | |
| 39 #include "stdpackets.h" | |
|
2496
f0a2a9afdb77
[gaim-migrate @ 2509]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
40 #include "socketmanager.h" |
| 2086 | 41 |
| 42 icq_FileSession *icq_FileSessionNew(icq_Link *icqlink) | |
| 43 { | |
| 44 icq_FileSession *p=(icq_FileSession *)malloc(sizeof(icq_FileSession)); | |
| 45 | |
| 46 if (p) | |
| 47 { | |
| 48 p->status=0; | |
| 49 p->id=0L; | |
| 50 p->icqlink=icqlink; | |
| 51 p->tcplink=NULL; | |
| 52 p->current_fd=-1; | |
| 53 p->current_file_num=0; | |
| 54 p->current_file_progress=0; | |
| 55 p->current_file_size=0; | |
| 56 p->files=0L; | |
| 57 p->current_speed=100; | |
| 58 p->total_bytes=0; | |
| 59 p->total_files=0; | |
| 60 p->total_transferred_bytes=0; | |
| 61 p->working_dir[0]=0; | |
| 62 p->user_data=NULL; | |
| 63 icq_ListInsert(icqlink->d->icq_FileSessions, 0, p); | |
| 64 } | |
| 65 | |
| 66 return p; | |
| 67 } | |
| 68 | |
| 69 void icq_FileSessionDelete(void *pv) | |
| 70 { | |
| 71 icq_FileSession *p=(icq_FileSession *)pv; | |
| 72 | |
| 73 invoke_callback(p->icqlink, icq_FileNotify)(p, FILE_NOTIFY_CLOSE, 0, | |
| 74 NULL); | |
| 75 | |
| 76 if(p->files) { | |
| 77 char **p2=p->files; | |
| 78 while(*p2) | |
| 79 free(*(p2++)); | |
| 80 free(p->files); | |
| 81 p->files=NULL; | |
| 82 } | |
| 83 | |
| 84 if (p->current_fd > -1 ) { | |
| 85 close(p->current_fd); | |
| 86 p->current_fd=-1; | |
| 87 } | |
| 88 | |
| 89 free(p); | |
| 90 } | |
| 91 | |
| 92 int _icq_FindFileSession(void *p, va_list data) | |
| 93 { | |
| 94 icq_FileSession *psession=(icq_FileSession *)p; | |
| 95 DWORD uin=va_arg(data, DWORD); | |
| 96 unsigned long id=va_arg(data, unsigned long); | |
| 97 | |
| 98 return (psession->remote_uin == uin) && ( id ? (psession->id == id) : 1 ); | |
| 99 | |
| 100 } | |
| 101 | |
| 102 icq_FileSession *icq_FindFileSession(icq_Link *icqlink, DWORD uin, | |
| 103 unsigned long id) | |
| 104 { | |
| 105 return icq_ListTraverse(icqlink->d->icq_FileSessions, _icq_FindFileSession, | |
| 106 uin, id); | |
| 107 } | |
| 108 | |
| 109 void icq_FileSessionSetStatus(icq_FileSession *p, int status) | |
| 110 { | |
| 111 if(status!=p->status) | |
| 112 { | |
| 113 p->status=status; | |
| 114 if(p->id) | |
| 115 invoke_callback(p->icqlink, icq_FileNotify)(p, FILE_NOTIFY_STATUS, | |
| 116 status, NULL); | |
| 117 if (status == FILE_STATUS_SENDING) | |
| 118 icq_SocketSetHandler(p->tcplink->socket, ICQ_SOCKET_WRITE, | |
|
2496
f0a2a9afdb77
[gaim-migrate @ 2509]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
119 (icq_SocketHandler)icq_FileSessionSendData, p); |
| 2086 | 120 else |
| 121 icq_SocketSetHandler(p->tcplink->socket, ICQ_SOCKET_WRITE, NULL, NULL); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void icq_FileSessionSetHandle(icq_FileSession *p, const char *handle) | |
| 126 { | |
| 127 strncpy(p->remote_handle, handle, 64); | |
| 128 } | |
| 129 | |
| 130 void icq_FileSessionSetCurrentFile(icq_FileSession *p, const char *filename) | |
| 131 { | |
| 132 #ifdef _WIN32 | |
| 133 struct _stat file_status; | |
| 134 #else | |
| 135 struct stat file_status; | |
| 136 #endif | |
| 137 char file[1024]; | |
| 138 | |
| 139 strcpy(file, p->working_dir); | |
| 140 strcat(file, filename); | |
| 141 | |
| 142 if (p->current_fd>-1) { | |
| 143 close(p->current_fd); | |
| 144 p->current_fd=-1; | |
| 145 } | |
| 146 | |
| 147 strncpy(p->current_file, file, 64); | |
| 148 p->current_file_progress=0; | |
| 149 | |
| 150 /* does the file already exist? */ | |
| 151 #ifdef _WIN32 | |
| 152 if (_stat(file, &file_status)==0) { | |
| 153 #else | |
| 154 if (stat(file, &file_status)==0) { | |
| 155 #endif | |
| 156 p->current_file_progress=file_status.st_size; | |
| 157 p->total_transferred_bytes+=file_status.st_size; | |
| 158 #ifdef _WIN32 | |
| 159 p->current_fd=open(file, _O_WRONLY | _O_APPEND | _O_BINARY); | |
| 160 #else | |
| 161 p->current_fd=open(file, O_WRONLY | O_APPEND); | |
| 162 #endif | |
| 163 } else { | |
| 164 #ifdef _WIN32 | |
| 165 p->current_fd=open(file, _O_WRONLY | _O_CREAT | _O_BINARY, | |
| 166 _S_IREAD|_S_IWRITE); | |
| 167 #else | |
| 168 p->current_fd=open(file, O_WRONLY | O_CREAT, S_IRWXU); | |
| 169 #endif | |
| 170 } | |
| 171 | |
| 172 /* make sure we have a valid filehandle */ | |
| 173 if (p->current_fd == -1) | |
| 174 perror("couldn't open file: "); | |
| 175 | |
| 176 } | |
| 177 | |
| 178 void icq_FileSessionPrepareNextFile(icq_FileSession *p) | |
| 179 { | |
| 180 int i=0; | |
| 181 char **files=p->files; | |
| 182 | |
| 183 p->current_file_num++; | |
| 184 | |
| 185 while(*files) { | |
| 186 i++; | |
| 187 if(i==p->current_file_num) | |
| 188 break; | |
| 189 else | |
| 190 files++; | |
| 191 } | |
| 192 | |
| 193 if(*files) { | |
| 194 #ifdef _WIN32 | |
| 195 struct _stat file_status; | |
| 196 #else | |
| 197 struct stat file_status; | |
| 198 #endif | |
| 199 | |
| 200 if (p->current_fd>-1) { | |
| 201 close(p->current_fd); | |
| 202 p->current_fd=-1; | |
| 203 } | |
| 204 | |
| 205 #ifdef _WIN32 | |
| 206 if (_stat(*files, &file_status)==0) { | |
| 207 char *basename=*files; | |
| 208 char *pos=strrchr(basename, '\\'); | |
| 209 #else | |
| 210 if (stat(*files, &file_status)==0) { | |
| 211 char *basename=*files; | |
| 212 char *pos=strrchr(basename, '/'); | |
| 213 #endif | |
| 214 if(pos) basename=pos+1; | |
| 215 strncpy(p->current_file, basename, 64); | |
| 216 p->current_file_progress=0; | |
| 217 p->current_file_size=file_status.st_size; | |
| 218 #ifdef _WIN32 | |
| 219 p->current_fd=open(*files, _O_RDONLY | _O_BINARY); | |
| 220 #else | |
| 221 p->current_fd=open(*files, O_RDONLY); | |
| 222 #endif | |
| 223 } | |
| 224 | |
| 225 /* make sure we have a valid filehandle */ | |
| 226 if (p->current_fd == -1) | |
| 227 perror("couldn't open file: "); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 void icq_FileSessionSendData(icq_FileSession *p) | |
| 232 { | |
| 233 /* for now just send a packet at a time */ | |
| 234 char buffer[2048]; | |
| 235 int count=read(p->current_fd, buffer, 2048); | |
| 236 | |
| 237 if(count>0) { | |
| 238 icq_Packet *p2=icq_TCPCreateFile06Packet(count, buffer); | |
| 239 icq_TCPLinkSend(p->tcplink, p2); | |
| 240 p->total_transferred_bytes+=count; | |
| 241 p->current_file_progress+=count; | |
| 242 icq_FileSessionSetStatus(p, FILE_STATUS_SENDING); | |
| 243 | |
| 244 invoke_callback(p->icqlink, icq_FileNotify)(p, FILE_NOTIFY_DATAPACKET, | |
| 245 count, buffer); | |
| 246 } | |
| 247 | |
| 248 /* done transmitting if read returns less that 2048 bytes */ | |
| 249 if(count<2048) | |
| 250 icq_FileSessionClose(p); | |
| 251 | |
| 252 return; | |
| 253 } | |
| 254 | |
| 255 /* public */ | |
| 256 | |
| 257 void icq_FileSessionSetSpeed(icq_FileSession *p, int speed) | |
| 258 { | |
| 259 icq_Packet *packet=icq_TCPCreateFile05Packet(speed); | |
| 260 | |
| 261 icq_TCPLinkSend(p->tcplink, packet); | |
| 262 } | |
| 263 | |
| 264 void icq_FileSessionClose(icq_FileSession *p) | |
| 265 { | |
| 266 icq_TCPLink *plink=p->tcplink; | |
| 267 | |
| 268 /* TODO: handle closing already unallocated filesession? */ | |
| 269 | |
| 270 /* if we're attached to a tcplink, unattach so the link doesn't try | |
| 271 * to close us, and then close the tcplink */ | |
| 272 if (plink) | |
| 273 { | |
| 274 plink->session=0L; | |
| 275 icq_TCPLinkClose(plink); | |
| 276 } | |
| 277 | |
| 278 icq_ListRemove(p->icqlink->d->icq_FileSessions, p); | |
| 279 icq_FileSessionDelete(p); | |
| 280 } | |
| 281 | |
| 282 void icq_FileSessionSetWorkingDir(icq_FileSession *p, const char *dir) | |
| 283 { | |
| 284 int length = sizeof(p->working_dir); | |
| 285 strncpy(p->working_dir, dir, length); | |
| 286 p->working_dir[length-1]='\0'; | |
| 287 } | |
| 288 | |
| 289 void icq_FileSessionSetFiles(icq_FileSession *p, char **files) | |
| 290 { | |
| 291 p->files=files; | |
| 292 } | |
| 293 |
