Mercurial > pidgin.yaz
comparison src/ft.c @ 7805:5f0bb52c0609
[gaim-migrate @ 8452]
File transfer changes from marv.
This fixes various ft related bugs, including:
* Sometimes clicking cancel on a send would crash.
* We seemed to leak the GaimXfer most of the time.
* Choosing to not overwrite the file would cancel the
receive altogether.
This should fix all these issues. It would be nice if
someone (SimGuy?) could test this for me, especially on
windows, to make sure i didn't break anything. Jabber
ft is untested, althoughi didn't make any changes in
the jabber source. So, it should still work, i just
can't comfirm it. Yahoo and OSCAR do still work.
Amoung other things, this patch impliments some
reference counting on the GaimXfer, so the ui can keep
it around a while if it wants, without leaking it
because we're afraid to destroy it.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 08 Dec 2003 04:58:07 +0000 |
parents | b14442b31a9b |
children | 8e60ddc28a22 |
comparison
equal
deleted
inserted
replaced
7804:622c9149609c | 7805:5f0bb52c0609 |
---|---|
38 g_return_val_if_fail(account != NULL, NULL); | 38 g_return_val_if_fail(account != NULL, NULL); |
39 g_return_val_if_fail(who != NULL, NULL); | 39 g_return_val_if_fail(who != NULL, NULL); |
40 | 40 |
41 xfer = g_new0(GaimXfer, 1); | 41 xfer = g_new0(GaimXfer, 1); |
42 | 42 |
43 xfer->ref = 1; | |
43 xfer->type = type; | 44 xfer->type = type; |
44 xfer->account = account; | 45 xfer->account = account; |
45 xfer->who = g_strdup(who); | 46 xfer->who = g_strdup(who); |
46 xfer->ui_ops = gaim_xfers_get_ui_ops(); | 47 xfer->ui_ops = gaim_xfers_get_ui_ops(); |
47 | 48 |
53 ui_ops->new_xfer(xfer); | 54 ui_ops->new_xfer(xfer); |
54 | 55 |
55 return xfer; | 56 return xfer; |
56 } | 57 } |
57 | 58 |
58 void | 59 static void |
59 gaim_xfer_destroy(GaimXfer *xfer) | 60 gaim_xfer_destroy(GaimXfer *xfer) |
60 { | 61 { |
61 GaimXferUiOps *ui_ops; | 62 GaimXferUiOps *ui_ops; |
62 | 63 |
63 g_return_if_fail(xfer != NULL); | 64 g_return_if_fail(xfer != NULL); |
64 | 65 |
65 if (!xfer->completed) | 66 if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_STARTED) |
66 gaim_xfer_cancel_local(xfer); | 67 gaim_xfer_cancel_local(xfer); |
67 | 68 |
68 ui_ops = gaim_xfer_get_ui_ops(xfer); | 69 ui_ops = gaim_xfer_get_ui_ops(xfer); |
69 | 70 |
70 if (ui_ops != NULL && ui_ops->destroy != NULL) | 71 if (ui_ops != NULL && ui_ops->destroy != NULL) |
81 | 82 |
82 g_free(xfer); | 83 g_free(xfer); |
83 } | 84 } |
84 | 85 |
85 void | 86 void |
87 gaim_xfer_ref(GaimXfer *xfer) | |
88 { | |
89 g_return_if_fail(xfer != NULL); | |
90 | |
91 xfer->ref++; | |
92 } | |
93 | |
94 void | |
95 gaim_xfer_unref(GaimXfer *xfer) | |
96 { | |
97 g_return_if_fail(xfer != NULL); | |
98 | |
99 xfer->ref--; | |
100 | |
101 if (xfer->ref == 0) | |
102 gaim_xfer_destroy(xfer); | |
103 } | |
104 | |
105 void | |
86 gaim_xfer_request(GaimXfer *xfer) | 106 gaim_xfer_request(GaimXfer *xfer) |
87 { | 107 { |
88 GaimXferUiOps *ui_ops; | 108 GaimXferUiOps *ui_ops; |
89 | 109 |
90 g_return_if_fail(xfer != NULL); | 110 g_return_if_fail(xfer != NULL); |
97 | 117 |
98 ui_ops->request_file(xfer); | 118 ui_ops->request_file(xfer); |
99 } | 119 } |
100 | 120 |
101 void | 121 void |
102 gaim_xfer_request_accepted(GaimXfer *xfer, char *filename) | 122 gaim_xfer_request_accepted(GaimXfer *xfer, const char *filename) |
103 { | 123 { |
104 GaimXferType type; | 124 GaimXferType type; |
105 | 125 |
106 if (xfer == NULL || filename == NULL) { | 126 if (xfer == NULL || filename == NULL) { |
107 | |
108 if (filename != NULL) | |
109 g_free(filename); | |
110 | |
111 return; | 127 return; |
112 } | 128 } |
113 | 129 |
114 type = gaim_xfer_get_type(xfer); | 130 type = gaim_xfer_get_type(xfer); |
115 | 131 |
124 filename); | 140 filename); |
125 | 141 |
126 gaim_xfer_error(type, xfer->who, msg); | 142 gaim_xfer_error(type, xfer->who, msg); |
127 | 143 |
128 g_free(msg); | 144 g_free(msg); |
129 g_free(filename); | 145 gaim_xfer_unref(xfer); |
130 | |
131 return; | 146 return; |
132 } | 147 } |
133 | 148 |
134 if (stat(filename, &sb) == -1) { | 149 if (stat(filename, &sb) == -1) { |
135 char *msg; | 150 char *msg; |
137 msg = g_strdup_printf(_("%s was not found.\n"), filename); | 152 msg = g_strdup_printf(_("%s was not found.\n"), filename); |
138 | 153 |
139 gaim_xfer_error(type, xfer->who, msg); | 154 gaim_xfer_error(type, xfer->who, msg); |
140 | 155 |
141 g_free(msg); | 156 g_free(msg); |
142 g_free(filename); | 157 gaim_xfer_unref(xfer); |
143 | |
144 return; | 158 return; |
145 } | 159 } |
146 | 160 |
147 gaim_xfer_set_local_filename(xfer, filename); | 161 gaim_xfer_set_local_filename(xfer, filename); |
148 gaim_xfer_set_size(xfer, sb.st_size); | 162 gaim_xfer_set_size(xfer, sb.st_size); |
151 /* TODO: Sanity checks and file overwrite checks. */ | 165 /* TODO: Sanity checks and file overwrite checks. */ |
152 | 166 |
153 gaim_xfer_set_local_filename(xfer, filename); | 167 gaim_xfer_set_local_filename(xfer, filename); |
154 } | 168 } |
155 | 169 |
156 g_free(filename); | |
157 | 170 |
158 xfer->ops.init(xfer); | 171 xfer->ops.init(xfer); |
159 } | 172 } |
160 | 173 |
161 void | 174 void |
162 gaim_xfer_request_denied(GaimXfer *xfer) | 175 gaim_xfer_request_denied(GaimXfer *xfer) |
163 { | 176 { |
164 g_return_if_fail(xfer != NULL); | 177 g_return_if_fail(xfer != NULL); |
165 | 178 |
166 gaim_xfer_destroy(xfer); | 179 if (xfer->ops.request_denied != NULL) |
167 | 180 xfer->ops.request_denied(xfer); |
168 /* TODO */ | 181 |
182 gaim_xfer_unref(xfer); | |
169 } | 183 } |
170 | 184 |
171 GaimXferType | 185 GaimXferType |
172 gaim_xfer_get_type(const GaimXfer *xfer) | 186 gaim_xfer_get_type(const GaimXfer *xfer) |
173 { | 187 { |
182 g_return_val_if_fail(xfer != NULL, NULL); | 196 g_return_val_if_fail(xfer != NULL, NULL); |
183 | 197 |
184 return xfer->account; | 198 return xfer->account; |
185 } | 199 } |
186 | 200 |
187 GaimXferCancelType | 201 GaimXferStatusType |
202 gaim_xfer_get_status(const GaimXfer *xfer) | |
203 { | |
204 g_return_val_if_fail(xfer != NULL, GAIM_XFER_STATUS_UNKNOWN); | |
205 | |
206 return xfer->status; | |
207 } | |
208 | |
209 gboolean | |
188 gaim_xfer_is_canceled(const GaimXfer *xfer) | 210 gaim_xfer_is_canceled(const GaimXfer *xfer) |
189 { | 211 { |
190 g_return_val_if_fail(xfer != NULL, TRUE); | 212 g_return_val_if_fail(xfer != NULL, TRUE); |
191 | 213 |
192 return xfer->canceled; | 214 if ((gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) || |
215 (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_REMOTE)) | |
216 return TRUE; | |
217 else | |
218 return FALSE; | |
193 } | 219 } |
194 | 220 |
195 gboolean | 221 gboolean |
196 gaim_xfer_is_completed(const GaimXfer *xfer) | 222 gaim_xfer_is_completed(const GaimXfer *xfer) |
197 { | 223 { |
198 g_return_val_if_fail(xfer != NULL, TRUE); | 224 g_return_val_if_fail(xfer != NULL, TRUE); |
199 | 225 |
200 return xfer->completed; | 226 return (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_DONE); |
201 } | 227 } |
202 | 228 |
203 const char * | 229 const char * |
204 gaim_xfer_get_filename(const GaimXfer *xfer) | 230 gaim_xfer_get_filename(const GaimXfer *xfer) |
205 { | 231 { |
283 | 309 |
284 return xfer->remote_port; | 310 return xfer->remote_port; |
285 } | 311 } |
286 | 312 |
287 static void | 313 static void |
288 gaim_xfer_set_canceled(GaimXfer *xfer, GaimXferCancelType canceled) | 314 gaim_xfer_set_status(GaimXfer *xfer, GaimXferStatusType status) |
289 { | 315 { |
290 g_return_if_fail(xfer != NULL); | 316 g_return_if_fail(xfer != NULL); |
291 | 317 |
292 xfer->canceled = canceled; | 318 xfer->status = status; |
293 } | 319 } |
294 | 320 |
295 void | 321 void |
296 gaim_xfer_set_completed(GaimXfer *xfer, gboolean completed) | 322 gaim_xfer_set_completed(GaimXfer *xfer, gboolean completed) |
297 { | 323 { |
298 GaimXferUiOps *ui_ops; | 324 GaimXferUiOps *ui_ops; |
299 | 325 |
300 g_return_if_fail(xfer != NULL); | 326 g_return_if_fail(xfer != NULL); |
301 | 327 |
302 xfer->completed = completed; | 328 if (completed == TRUE) |
329 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_DONE); | |
303 | 330 |
304 ui_ops = gaim_xfer_get_ui_ops(xfer); | 331 ui_ops = gaim_xfer_get_ui_ops(xfer); |
305 | 332 |
306 if (ui_ops != NULL && ui_ops->update_progress != NULL) | 333 if (ui_ops != NULL && ui_ops->update_progress != NULL) |
307 ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); | 334 ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); |
355 g_return_if_fail(xfer != NULL); | 382 g_return_if_fail(xfer != NULL); |
356 | 383 |
357 xfer->ops.init = fnc; | 384 xfer->ops.init = fnc; |
358 } | 385 } |
359 | 386 |
387 void gaim_xfer_set_request_denied_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
388 { | |
389 g_return_if_fail(xfer != NULL); | |
390 | |
391 xfer->ops.request_denied = fnc; | |
392 } | |
360 | 393 |
361 void | 394 void |
362 gaim_xfer_set_read_fnc(GaimXfer *xfer, size_t (*fnc)(char **, GaimXfer *)) | 395 gaim_xfer_set_read_fnc(GaimXfer *xfer, size_t (*fnc)(char **, GaimXfer *)) |
363 { | 396 { |
364 g_return_if_fail(xfer != NULL); | 397 g_return_if_fail(xfer != NULL); |
563 type = gaim_xfer_get_type(xfer); | 596 type = gaim_xfer_get_type(xfer); |
564 | 597 |
565 xfer->bytes_remaining = gaim_xfer_get_size(xfer); | 598 xfer->bytes_remaining = gaim_xfer_get_size(xfer); |
566 xfer->bytes_sent = 0; | 599 xfer->bytes_sent = 0; |
567 | 600 |
601 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_STARTED); | |
602 | |
568 if (type == GAIM_XFER_RECEIVE) { | 603 if (type == GAIM_XFER_RECEIVE) { |
569 cond = GAIM_INPUT_READ; | 604 cond = GAIM_INPUT_READ; |
570 | 605 |
571 if (ip != NULL) { | 606 if (ip != NULL) { |
572 xfer->remote_ip = g_strdup(ip); | 607 xfer->remote_ip = g_strdup(ip); |
595 gaim_xfer_end(GaimXfer *xfer) | 630 gaim_xfer_end(GaimXfer *xfer) |
596 { | 631 { |
597 g_return_if_fail(xfer != NULL); | 632 g_return_if_fail(xfer != NULL); |
598 | 633 |
599 /* See if we are actually trying to cancel this. */ | 634 /* See if we are actually trying to cancel this. */ |
600 if (!xfer->completed) { | 635 if (gaim_xfer_get_status(xfer) != GAIM_XFER_STATUS_DONE) { |
601 gaim_xfer_cancel_local(xfer); | 636 gaim_xfer_cancel_local(xfer); |
602 return; | 637 return; |
603 } | 638 } |
604 | 639 |
605 if (xfer->ops.end != NULL) | 640 if (xfer->ops.end != NULL) |
615 | 650 |
616 if (xfer->dest_fp != NULL) { | 651 if (xfer->dest_fp != NULL) { |
617 fclose(xfer->dest_fp); | 652 fclose(xfer->dest_fp); |
618 xfer->dest_fp = NULL; | 653 xfer->dest_fp = NULL; |
619 } | 654 } |
655 | |
656 gaim_xfer_unref(xfer); | |
620 } | 657 } |
621 | 658 |
622 void | 659 void |
623 gaim_xfer_cancel_local(GaimXfer *xfer) | 660 gaim_xfer_cancel_local(GaimXfer *xfer) |
624 { | 661 { |
625 GaimXferUiOps *ui_ops; | 662 GaimXferUiOps *ui_ops; |
626 | 663 |
627 g_return_if_fail(xfer != NULL); | 664 g_return_if_fail(xfer != NULL); |
628 | 665 |
629 gaim_xfer_set_canceled(xfer, GAIM_XFER_CANCEL_LOCAL); | 666 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_LOCAL); |
630 | 667 |
631 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) | 668 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) |
632 { | 669 { |
633 if (xfer->ops.cancel_send != NULL) | 670 if (xfer->ops.cancel_send != NULL) |
634 xfer->ops.cancel_send(xfer); | 671 xfer->ops.cancel_send(xfer); |
656 | 693 |
657 if (ui_ops != NULL && ui_ops->cancel_local != NULL) | 694 if (ui_ops != NULL && ui_ops->cancel_local != NULL) |
658 ui_ops->cancel_local(xfer); | 695 ui_ops->cancel_local(xfer); |
659 | 696 |
660 xfer->bytes_remaining = 0; | 697 xfer->bytes_remaining = 0; |
698 | |
699 gaim_xfer_unref(xfer); | |
661 } | 700 } |
662 | 701 |
663 void | 702 void |
664 gaim_xfer_cancel_remote(GaimXfer *xfer) | 703 gaim_xfer_cancel_remote(GaimXfer *xfer) |
665 { | 704 { |
666 GaimXferUiOps *ui_ops; | 705 GaimXferUiOps *ui_ops; |
667 | 706 |
668 g_return_if_fail(xfer != NULL); | 707 g_return_if_fail(xfer != NULL); |
669 | 708 |
670 gaim_xfer_set_canceled(xfer, GAIM_XFER_CANCEL_REMOTE); | 709 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_REMOTE); |
671 | 710 |
672 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) | 711 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) |
673 { | 712 { |
674 if (xfer->ops.cancel_send != NULL) | 713 if (xfer->ops.cancel_send != NULL) |
675 xfer->ops.cancel_send(xfer); | 714 xfer->ops.cancel_send(xfer); |
697 | 736 |
698 if (ui_ops != NULL && ui_ops->cancel_remote != NULL) | 737 if (ui_ops != NULL && ui_ops->cancel_remote != NULL) |
699 ui_ops->cancel_remote(xfer); | 738 ui_ops->cancel_remote(xfer); |
700 | 739 |
701 xfer->bytes_remaining = 0; | 740 xfer->bytes_remaining = 0; |
741 | |
742 gaim_xfer_unref(xfer); | |
702 } | 743 } |
703 | 744 |
704 void | 745 void |
705 gaim_xfer_error(GaimXferType type, const char *who, const char *msg) | 746 gaim_xfer_error(GaimXferType type, const char *who, const char *msg) |
706 { | 747 { |