Mercurial > gftp.yaz
annotate lib/local.c @ 65:4b5fec7711e9
2002-11-25 Brian Masney <masneyb@gftp.org>
* lib/misc.c (ssh_start_login_sequence) - fixes for when the initial
SSH banner is bigger than 200 characters
* lib/local.c (local_connect) - set request->hostname to local
filesystem
* lib/protocols.c (gftp_parse_url) - don't include 2 slashes for
the directory when parsing a local URL
* src/gtk/chmod_dialog.c (chmod_dialog) - allow multiple files to be
selected
* src/gtk/dnd.c - small fixes
author | masneyb |
---|---|
date | Tue, 26 Nov 2002 14:58:13 +0000 |
parents | 41b71c4e5076 |
children | cd3e457cbc85 |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* local.c - functions that will use the local system */ | |
3 /* Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org> */ | |
4 /* */ | |
5 /* This program is free software; you can redistribute it and/or modify */ | |
6 /* it under the terms of the GNU General Public License as published by */ | |
7 /* the Free Software Foundation; either version 2 of the License, or */ | |
8 /* (at your option) any later version. */ | |
9 /* */ | |
10 /* This program is distributed in the hope that it will be useful, */ | |
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | |
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | |
13 /* GNU General Public License for more details. */ | |
14 /* */ | |
15 /* You should have received a copy of the GNU General Public License */ | |
16 /* along with this program; if not, write to the Free Software */ | |
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ | |
18 /*****************************************************************************/ | |
19 | |
20 #include "gftp.h" | |
33 | 21 static const char cvsid[] = "$Id$"; |
1 | 22 |
23 typedef struct local_protocol_data_tag | |
24 { | |
25 DIR *dir; | |
26 GHashTable *userhash, *grouphash; | |
27 } local_protocol_data; | |
28 | |
29 | |
48 | 30 static void |
31 local_remove_key (gpointer key, gpointer value, gpointer user_data) | |
1 | 32 { |
48 | 33 g_free (value); |
1 | 34 } |
35 | |
36 | |
37 static void | |
38 local_destroy (gftp_request * request) | |
39 { | |
40 local_protocol_data * lpd; | |
41 | |
42 g_return_if_fail (request != NULL); | |
43 g_return_if_fail (request->protonum == GFTP_LOCAL_NUM); | |
44 | |
45 lpd = request->protocol_data; | |
46 g_hash_table_foreach (lpd->userhash, local_remove_key, NULL); | |
47 g_hash_table_destroy (lpd->userhash); | |
48 g_hash_table_foreach (lpd->grouphash, local_remove_key, NULL); | |
49 g_hash_table_destroy (lpd->grouphash); | |
50 lpd->userhash = lpd->grouphash = NULL; | |
51 } | |
52 | |
53 | |
54 static int | |
55 local_connect (gftp_request * request) | |
56 { | |
57 char tempstr[PATH_MAX]; | |
58 | |
59 g_return_val_if_fail (request != NULL, -2); | |
60 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
61 | |
65 | 62 if (request->hostname == NULL) |
63 request->hostname = g_strdup (_("local filesystem")); | |
64 | |
1 | 65 if (request->directory) |
66 { | |
67 if (chdir (request->directory) != 0) | |
68 { | |
69 request->logging_function (gftp_logging_error, request->user_data, | |
70 _("Could not change local directory to %s: %s\n"), | |
71 request->directory, g_strerror (errno)); | |
72 } | |
73 g_free (request->directory); | |
74 request->directory = NULL; | |
75 } | |
76 | |
77 if (getcwd (tempstr, sizeof (tempstr)) != NULL) | |
78 { | |
79 tempstr[sizeof (tempstr) - 1] = '\0'; | |
80 request->directory = g_malloc (strlen (tempstr) + 1); | |
81 strcpy (request->directory, tempstr); | |
82 } | |
83 else | |
84 request->logging_function (gftp_logging_error, request->user_data, | |
85 _("Could not get current working directory: %s\n"), | |
86 g_strerror (errno)); | |
87 | |
88 return (0); | |
89 } | |
90 | |
91 | |
92 static void | |
93 local_disconnect (gftp_request * request) | |
94 { | |
95 g_return_if_fail (request != NULL); | |
96 g_return_if_fail (request->protonum == GFTP_LOCAL_NUM); | |
97 | |
58 | 98 if (request->datafd != -1) |
1 | 99 { |
58 | 100 if (close (request->datafd) < 0) |
1 | 101 request->logging_function (gftp_logging_error, request->user_data, |
102 _("Error closing file descriptor: %s\n"), | |
103 g_strerror (errno)); | |
58 | 104 request->datafd = -1; |
1 | 105 } |
106 } | |
107 | |
108 | |
58 | 109 static off_t |
110 local_get_file (gftp_request * request, const char *filename, int fd, | |
1 | 111 off_t startsize) |
112 { | |
58 | 113 off_t size; |
114 int flags; | |
1 | 115 |
116 g_return_val_if_fail (request != NULL, -2); | |
117 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
118 g_return_val_if_fail (filename != NULL, -2); | |
119 | |
58 | 120 if (fd > 0) |
1 | 121 { |
7 | 122 flags = O_RDONLY; |
123 #if defined (_LARGEFILE_SOURCE) | |
124 flags |= O_LARGEFILE; | |
125 #endif | |
126 | |
58 | 127 if ((request->datafd = open (filename, flags)) < 0) |
1 | 128 { |
129 request->logging_function (gftp_logging_error, request->user_data, | |
130 _("Error: Cannot open local file %s: %s\n"), | |
131 filename, g_strerror (errno)); | |
132 return (-2); | |
133 } | |
134 } | |
135 else | |
136 request->datafd = fd; | |
137 | |
58 | 138 if ((size = lseek (request->datafd, 0, SEEK_END)) == -1) |
1 | 139 { |
140 request->logging_function (gftp_logging_error, request->user_data, | |
141 _("Error: Cannot seek on file %s: %s\n"), | |
142 filename, g_strerror (errno)); | |
58 | 143 gftp_disconnect (request); |
144 return (-1); | |
1 | 145 } |
146 | |
58 | 147 if (lseek (request->datafd, startsize, SEEK_SET) == -1) |
1 | 148 { |
149 request->logging_function (gftp_logging_error, request->user_data, | |
150 _("Error: Cannot seek on file %s: %s\n"), | |
151 filename, g_strerror (errno)); | |
58 | 152 gftp_disconnect (request); |
153 return (-1); | |
1 | 154 } |
155 | |
156 return (size); | |
157 } | |
158 | |
159 | |
160 static int | |
58 | 161 local_put_file (gftp_request * request, const char *filename, int fd, |
1 | 162 off_t startsize, off_t totalsize) |
163 { | |
58 | 164 int flags; |
1 | 165 |
166 g_return_val_if_fail (request != NULL, -2); | |
167 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
168 g_return_val_if_fail (filename != NULL, -2); | |
169 | |
62 | 170 if (fd < 0) |
1 | 171 { |
7 | 172 flags = O_WRONLY | O_CREAT; |
173 if (startsize > 0) | |
174 flags |= O_APPEND; | |
175 #if defined (_LARGEFILE_SOURCE) | |
176 flags |= O_LARGEFILE; | |
177 #endif | |
178 | |
58 | 179 if ((request->datafd = open (filename, flags, S_IRUSR | S_IWUSR)) < 0) |
1 | 180 { |
181 request->logging_function (gftp_logging_error, request->user_data, | |
182 _("Error: Cannot open local file %s: %s\n"), | |
183 filename, g_strerror (errno)); | |
184 return (-2); | |
185 } | |
186 } | |
187 else | |
188 request->datafd = fd; | |
189 | |
58 | 190 if (ftruncate (request->datafd, startsize) == -1) |
1 | 191 { |
192 request->logging_function (gftp_logging_error, request->user_data, | |
193 _("Error: Cannot truncate local file %s: %s\n"), | |
194 filename, g_strerror (errno)); | |
58 | 195 gftp_disconnect (request); |
196 return (-1); | |
1 | 197 } |
198 | |
58 | 199 if (lseek (request->datafd, startsize, SEEK_SET) == -1) |
1 | 200 { |
201 request->logging_function (gftp_logging_error, request->user_data, | |
202 _("Error: Cannot seek on file %s: %s\n"), | |
203 filename, g_strerror (errno)); | |
58 | 204 gftp_disconnect (request); |
1 | 205 return (-2); |
206 } | |
207 return (0); | |
208 } | |
209 | |
210 | |
211 static int | |
212 local_end_transfer (gftp_request * request) | |
213 { | |
214 local_protocol_data * lpd; | |
215 | |
216 lpd = request->protocol_data; | |
217 if (lpd->dir) | |
218 { | |
219 closedir (lpd->dir); | |
220 lpd->dir = NULL; | |
221 } | |
222 | |
58 | 223 if (request->datafd > 0) |
1 | 224 { |
58 | 225 if (close (request->datafd) < 0) |
1 | 226 request->logging_function (gftp_logging_error, request->user_data, |
227 _("Error closing file descriptor: %s\n"), | |
228 g_strerror (errno)); | |
229 | |
58 | 230 request->datafd = -1; |
1 | 231 } |
232 | |
233 return (0); | |
234 } | |
235 | |
236 | |
48 | 237 static char * |
238 make_text_mode (gftp_file * fle, mode_t mode) | |
239 { | |
240 char *str; | |
241 | |
242 str = g_malloc0 (11); | |
243 | |
244 str[0] = '?'; | |
245 if (S_ISREG (mode)) | |
246 str[0] = '-'; | |
247 | |
248 if (S_ISLNK (mode)) | |
249 { | |
250 fle->islink = 1; | |
251 str[0] = 'l'; | |
252 } | |
253 | |
254 if (S_ISBLK (mode)) | |
255 { | |
256 fle->isblock = 1; | |
257 str[0] = 'b'; | |
258 } | |
259 | |
260 if (S_ISCHR (mode)) | |
261 { | |
262 fle->ischar = 1; | |
263 str[0] = 'c'; | |
264 } | |
265 | |
266 if (S_ISFIFO (mode)) | |
267 { | |
268 fle->isfifo = 1; | |
269 str[0] = 'p'; | |
270 } | |
271 | |
272 if (S_ISSOCK (mode)) | |
273 { | |
274 fle->issocket = 1; | |
275 str[0] = 's'; | |
276 } | |
277 | |
278 if (S_ISDIR (mode)) | |
279 { | |
280 fle->isdir = 1; | |
281 str[0] = 'd'; | |
282 } | |
283 | |
284 str[1] = mode & S_IRUSR ? 'r' : '-'; | |
285 str[2] = mode & S_IWUSR ? 'w' : '-'; | |
286 | |
287 if ((mode & S_ISUID) && (mode & S_IXUSR)) | |
288 str[3] = 's'; | |
289 else if (mode & S_ISUID) | |
290 str[3] = 'S'; | |
291 else if (mode & S_IXUSR) | |
292 str[3] = 'x'; | |
293 else | |
294 str[3] = '-'; | |
295 | |
296 str[4] = mode & S_IRGRP ? 'r' : '-'; | |
297 str[5] = mode & S_IWGRP ? 'w' : '-'; | |
298 | |
299 if ((mode & S_ISGID) && (mode & S_IXGRP)) | |
300 str[6] = 's'; | |
301 else if (mode & S_ISGID) | |
302 str[6] = 'S'; | |
303 else if (mode & S_IXGRP) | |
304 str[6] = 'x'; | |
305 else | |
306 str[6] = '-'; | |
307 | |
308 str[7] = mode & S_IROTH ? 'r' : '-'; | |
309 str[8] = mode & S_IWOTH ? 'w' : '-'; | |
310 | |
311 if ((mode & S_ISVTX) && (mode & S_IXOTH)) | |
312 str[9] = 't'; | |
313 else if (mode & S_ISVTX) | |
314 str[9] = 'T'; | |
315 else if (mode & S_IXOTH) | |
316 str[9] = 'x'; | |
317 else | |
318 str[9] = '-'; | |
319 return (str); | |
320 } | |
321 | |
322 | |
1 | 323 static int |
58 | 324 local_get_next_file (gftp_request * request, gftp_file * fle, int fd) |
1 | 325 { |
326 local_protocol_data * lpd; | |
327 struct dirent *dirp; | |
328 char *user, *group; | |
329 struct passwd *pw; | |
330 struct group *gr; | |
331 struct stat st; | |
332 | |
333 /* the struct passwd and struct group are not thread safe. But, | |
334 we're ok here because I have threading turned off for the local | |
335 protocol (see use_threads in local_init above) */ | |
336 g_return_val_if_fail (request != NULL, -2); | |
337 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
338 g_return_val_if_fail (fle != NULL, -2); | |
339 | |
340 lpd = request->protocol_data; | |
341 memset (fle, 0, sizeof (*fle)); | |
342 | |
343 if ((dirp = readdir (lpd->dir)) == NULL) | |
344 { | |
345 closedir (lpd->dir); | |
346 lpd->dir = NULL; | |
347 return (-2); | |
348 } | |
349 | |
350 fle->file = g_malloc (strlen (dirp->d_name) + 1); | |
351 strcpy (fle->file, dirp->d_name); | |
352 if (lstat (fle->file, &st) != 0) | |
353 { | |
354 closedir (lpd->dir); | |
355 lpd->dir = NULL; | |
356 return (-2); | |
357 } | |
358 | |
359 if ((user = g_hash_table_lookup (lpd->userhash, | |
360 GUINT_TO_POINTER(st.st_uid))) != NULL) | |
361 { | |
362 fle->user = g_malloc (strlen (user) + 1); | |
363 strcpy (fle->user, user); | |
364 } | |
365 else | |
366 { | |
367 if ((pw = getpwuid (st.st_uid)) == NULL) | |
368 fle->user = g_strdup_printf ("%u", st.st_uid); | |
369 else | |
370 { | |
371 fle->user = g_malloc (strlen (pw->pw_name) + 1); | |
372 strcpy (fle->user, pw->pw_name); | |
373 } | |
374 | |
375 user = g_malloc (strlen (fle->user) + 1); | |
376 strcpy (user, fle->user); | |
377 g_hash_table_insert (lpd->userhash, GUINT_TO_POINTER (st.st_uid), user); | |
378 } | |
379 | |
380 if ((group = g_hash_table_lookup (lpd->grouphash, | |
381 GUINT_TO_POINTER(st.st_gid))) != NULL) | |
382 { | |
383 fle->group = g_malloc (strlen (group) + 1); | |
384 strcpy (fle->group, group); | |
385 } | |
386 else | |
387 { | |
388 if ((gr = getgrgid (st.st_gid)) == NULL) | |
389 fle->group = g_strdup_printf ("%u", st.st_gid); | |
390 else | |
391 { | |
392 fle->group = g_malloc (strlen (gr->gr_name) + 1); | |
393 strcpy (fle->group, gr->gr_name); | |
394 } | |
395 | |
396 group = g_malloc (strlen (fle->group) + 1); | |
397 strcpy (group, fle->group); | |
398 g_hash_table_insert (lpd->grouphash, GUINT_TO_POINTER (st.st_gid), group); | |
399 } | |
400 | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
401 fle->attribs = make_text_mode (fle, st.st_mode); |
1 | 402 fle->datetime = st.st_mtime; |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
403 |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
404 if ((fle->attribs[0] == 'b' || fle->attribs[0] == 'u' || |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
405 fle->attribs[0] == 'c')) |
48 | 406 fle->size = (off_t) st.st_rdev; |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
407 else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
408 fle->size = st.st_size; |
1 | 409 |
410 if (*fle->attribs == 'd') | |
411 fle->isdir = 1; | |
412 if (*fle->attribs == 'l') | |
413 fle->islink = 1; | |
414 if (strchr (fle->attribs, 'x') != NULL && !fle->isdir && !fle->islink) | |
415 fle->isexe = 1; | |
416 if (*fle->attribs == 'b') | |
417 fle->isblock = 1; | |
418 if (*fle->attribs == 'c') | |
419 fle->ischar = 1; | |
420 if (*fle->attribs == 's') | |
421 fle->issocket = 1; | |
422 if (*fle->attribs == 'p') | |
423 fle->isfifo = 1; | |
424 return (1); | |
425 } | |
426 | |
427 | |
428 static int | |
429 local_list_files (gftp_request * request) | |
430 { | |
431 local_protocol_data *lpd; | |
432 char *tempstr; | |
433 | |
434 g_return_val_if_fail (request != NULL, -2); | |
435 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
436 lpd = request->protocol_data; | |
437 | |
438 tempstr = g_strconcat (request->directory, "/", NULL); | |
439 | |
440 if ((lpd->dir = opendir (tempstr)) == NULL) | |
441 { | |
442 request->logging_function (gftp_logging_error, request->user_data, | |
443 _("Could not get local directory listing %s: %s\n"), | |
444 tempstr, g_strerror (errno)); | |
445 g_free (tempstr); | |
446 return (-1); | |
447 } | |
448 | |
449 g_free (tempstr); | |
450 return (0); | |
451 } | |
452 | |
453 | |
454 static off_t | |
455 local_get_file_size (gftp_request * request, const char *filename) | |
456 { | |
457 struct stat st; | |
458 | |
459 if (stat (filename, &st) == -1) | |
460 return (-1); | |
461 return (st.st_size); | |
462 } | |
463 | |
464 | |
465 static int | |
466 local_chdir (gftp_request * request, const char *directory) | |
467 { | |
468 char tempstr[255]; | |
469 | |
470 g_return_val_if_fail (request != NULL, -2); | |
471 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
472 g_return_val_if_fail (directory != NULL, -2); | |
473 | |
474 if (chdir (directory) == 0) | |
475 { | |
58 | 476 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 477 _("Successfully changed local directory to %s\n"), |
478 directory); | |
479 if (request->directory != directory) | |
480 { | |
481 if (getcwd (tempstr, sizeof (tempstr)) == NULL) | |
482 { | |
483 request->logging_function (gftp_logging_error, request->user_data, | |
484 _("Could not get current working directory: %s\n"), | |
485 g_strerror (errno)); | |
486 return (-1); | |
487 } | |
488 if (request->directory) | |
489 g_free (request->directory); | |
490 request->directory = g_malloc (strlen (tempstr) + 1); | |
491 strcpy (request->directory, tempstr); | |
492 } | |
493 return (0); | |
494 } | |
495 request->logging_function (gftp_logging_error, request->user_data, | |
496 _("Could not change local directory to %s: %s\n"), | |
497 directory, g_strerror (errno)); | |
498 return (-1); | |
499 } | |
500 | |
501 | |
502 static int | |
503 local_rmdir (gftp_request * request, const char *directory) | |
504 { | |
505 g_return_val_if_fail (request != NULL, -2); | |
506 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
507 g_return_val_if_fail (directory != NULL, -2); | |
508 | |
509 if (rmdir (directory) == 0) | |
510 { | |
58 | 511 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 512 _("Successfully removed %s\n"), directory); |
513 return (0); | |
514 } | |
515 else | |
516 { | |
517 request->logging_function (gftp_logging_error, request->user_data, | |
518 _("Error: Could not remove directory %s: %s\n"), | |
519 directory, g_strerror (errno)); | |
520 return (-1); | |
521 } | |
522 } | |
523 | |
524 | |
525 static int | |
526 local_rmfile (gftp_request * request, const char *file) | |
527 { | |
528 g_return_val_if_fail (request != NULL, -2); | |
529 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
530 g_return_val_if_fail (file != NULL, -2); | |
531 | |
532 if (unlink (file) == 0) | |
533 { | |
58 | 534 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 535 _("Successfully removed %s\n"), file); |
536 return (0); | |
537 } | |
538 else | |
539 { | |
540 request->logging_function (gftp_logging_error, request->user_data, | |
541 _("Error: Could not remove file %s: %s\n"), | |
542 file, g_strerror (errno)); | |
543 return (-1); | |
544 } | |
545 } | |
546 | |
547 | |
548 static int | |
549 local_mkdir (gftp_request * request, const char *directory) | |
550 { | |
551 g_return_val_if_fail (request != NULL, -2); | |
552 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
553 g_return_val_if_fail (directory != NULL, -2); | |
554 | |
555 if (mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) | |
556 { | |
58 | 557 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 558 _("Successfully made directory %s\n"), |
559 directory); | |
560 return (0); | |
561 } | |
562 else | |
563 { | |
564 request->logging_function (gftp_logging_error, request->user_data, | |
565 _("Error: Could not make directory %s: %s\n"), | |
566 directory, g_strerror (errno)); | |
567 return (-1); | |
568 } | |
569 } | |
570 | |
571 | |
572 static int | |
573 local_rename (gftp_request * request, const char *oldname, | |
574 const char *newname) | |
575 { | |
576 g_return_val_if_fail (request != NULL, -2); | |
577 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
578 g_return_val_if_fail (oldname != NULL, -2); | |
579 g_return_val_if_fail (newname != NULL, -2); | |
580 | |
581 if (rename (oldname, newname) == 0) | |
582 { | |
58 | 583 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 584 _("Successfully renamed %s to %s\n"), |
585 oldname, newname); | |
586 return (0); | |
587 } | |
588 else | |
589 { | |
590 request->logging_function (gftp_logging_error, request->user_data, | |
591 _("Error: Could not rename %s to %s: %s\n"), | |
592 oldname, newname, g_strerror (errno)); | |
593 return (-1); | |
594 } | |
595 } | |
596 | |
597 | |
598 static int | |
599 local_chmod (gftp_request * request, const char *file, int mode) | |
600 { | |
601 char buf[10]; | |
602 int newmode; | |
603 | |
604 g_return_val_if_fail (request != NULL, -2); | |
605 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
606 g_return_val_if_fail (file != NULL, -2); | |
607 | |
608 g_snprintf (buf, sizeof (buf), "%d", mode); | |
609 newmode = strtol (buf, NULL, 8); | |
610 | |
611 if (chmod (file, newmode) == 0) | |
612 { | |
58 | 613 request->logging_function (gftp_logging_misc, request->user_data, |
1 | 614 _("Successfully changed mode of %s to %d\n"), |
615 file, mode); | |
616 return (0); | |
617 } | |
618 else | |
619 { | |
620 request->logging_function (gftp_logging_error, request->user_data, | |
621 _("Error: Could not change mode of %s to %d: %s\n"), | |
622 file, mode, g_strerror (errno)); | |
623 return (-1); | |
624 } | |
625 } | |
626 | |
627 | |
628 static int | |
629 local_set_file_time (gftp_request * request, const char *file, | |
630 time_t datetime) | |
631 { | |
632 struct utimbuf time_buf; | |
633 | |
634 g_return_val_if_fail (request != NULL, -2); | |
635 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
636 g_return_val_if_fail (file != NULL, -2); | |
637 | |
638 time_buf.modtime = time_buf.actime = datetime; | |
639 return (utime (file, &time_buf)); | |
640 } | |
641 | |
642 | |
643 static gint | |
644 hash_compare (gconstpointer path1, gconstpointer path2) | |
645 { | |
646 return (GPOINTER_TO_UINT (path1) == GPOINTER_TO_UINT (path2)); | |
647 } | |
648 | |
649 | |
650 static guint | |
651 hash_function (gconstpointer key) | |
652 { | |
653 return (GPOINTER_TO_UINT (key)); | |
654 } | |
655 | |
48 | 656 |
657 void | |
658 local_init (gftp_request * request) | |
659 { | |
660 local_protocol_data *lpd; | |
661 | |
662 g_return_if_fail (request != NULL); | |
663 | |
664 request->protonum = GFTP_LOCAL_NUM; | |
665 request->init = local_init; | |
666 request->destroy = local_destroy; | |
667 request->connect = local_connect; | |
668 request->disconnect = local_disconnect; | |
669 request->get_file = local_get_file; | |
670 request->put_file = local_put_file; | |
671 request->transfer_file = NULL; | |
672 request->get_next_file_chunk = NULL; | |
673 request->put_next_file_chunk = NULL; | |
674 request->end_transfer = local_end_transfer; | |
675 request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ | |
676 request->list_files = local_list_files; | |
677 request->get_next_file = local_get_next_file; | |
678 request->set_data_type = NULL; | |
679 request->get_file_size = local_get_file_size; | |
680 request->chdir = local_chdir; | |
681 request->rmdir = local_rmdir; | |
682 request->rmfile = local_rmfile; | |
683 request->mkdir = local_mkdir; | |
684 request->rename = local_rename; | |
685 request->chmod = local_chmod; | |
686 request->set_file_time = local_set_file_time; | |
687 request->site = NULL; | |
688 request->parse_url = NULL; | |
58 | 689 request->set_config_options = NULL; |
63 | 690 request->swap_socks = NULL; |
48 | 691 request->url_prefix = "file"; |
692 request->protocol_name = "Local"; | |
693 request->need_hostport = 0; | |
694 request->need_userpass = 0; | |
695 request->use_cache = 0; | |
696 request->use_threads = 0; | |
697 request->always_connected = 1; | |
698 gftp_set_config_options (request); | |
699 | |
700 lpd = g_malloc0 (sizeof (*lpd)); | |
701 request->protocol_data = lpd; | |
702 lpd->userhash = g_hash_table_new (hash_function, hash_compare); | |
703 lpd->grouphash = g_hash_table_new (hash_function, hash_compare); | |
704 } | |
705 |