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