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