Mercurial > gftp.yaz
annotate lib/local.c @ 885:1808cebed602
2007-3-12 Brian Masney <masneyb@gftp.org>
* lib/* src/* - updated copyright dates
author | masneyb |
---|---|
date | Tue, 13 Mar 2007 01:52:50 +0000 |
parents | 1fae947d4418 |
children | 4ab11f70a7f4 |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* local.c - functions that will use the local system */ | |
885 | 3 /* Copyright (C) 1998-2007 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 |
787 | 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 | |
831 | 55 local_getcwd (gftp_request * request) |
56 { | |
57 char tempstr[PATH_MAX], *utf8; | |
838 | 58 size_t destlen; |
831 | 59 |
60 if (request->directory != NULL) | |
61 g_free (request->directory); | |
62 | |
63 if (getcwd (tempstr, sizeof (tempstr)) == NULL) | |
64 { | |
65 request->logging_function (gftp_logging_error, request, | |
66 _("Could not get current working directory: %s\n"), | |
67 g_strerror (errno)); | |
68 request->directory = NULL; | |
69 return (GFTP_ERETRYABLE); | |
70 } | |
71 | |
845 | 72 utf8 = gftp_filename_to_utf8 (request, tempstr, &destlen); |
831 | 73 if (utf8 != NULL) |
74 request->directory = utf8; | |
75 else | |
76 request->directory = g_strdup (tempstr); | |
77 | |
78 return (0); | |
79 } | |
80 | |
81 | |
82 static int | |
83 local_chdir (gftp_request * request, const char *directory) | |
84 { | |
838 | 85 size_t destlen; |
831 | 86 char *utf8; |
87 int ret; | |
88 | |
89 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
90 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
91 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
92 | |
845 | 93 utf8 = gftp_filename_from_utf8 (request, directory, &destlen); |
831 | 94 if (utf8 != NULL) |
95 { | |
96 ret = chdir (utf8); | |
97 g_free (utf8); | |
98 } | |
99 else | |
100 ret = chdir (directory); | |
101 | |
102 if (ret == 0) | |
103 { | |
104 request->logging_function (gftp_logging_misc, request, | |
105 _("Successfully changed local directory to %s\n"), | |
106 directory); | |
107 ret = local_getcwd (request); | |
108 } | |
109 else | |
110 { | |
111 request->logging_function (gftp_logging_error, request, | |
112 _("Could not change local directory to %s: %s\n"), | |
113 directory, g_strerror (errno)); | |
114 ret = GFTP_ERETRYABLE; | |
115 } | |
116 | |
117 return (ret); | |
118 } | |
119 | |
120 | |
121 static int | |
1 | 122 local_connect (gftp_request * request) |
123 { | |
84 | 124 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
125 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
1 | 126 |
510 | 127 if (request->directory != NULL) |
831 | 128 return (local_chdir (request, request->directory)); |
1 | 129 else |
831 | 130 return (local_getcwd (request)); |
1 | 131 } |
132 | |
133 | |
134 static void | |
135 local_disconnect (gftp_request * request) | |
136 { | |
137 g_return_if_fail (request != NULL); | |
138 g_return_if_fail (request->protonum == GFTP_LOCAL_NUM); | |
139 | |
58 | 140 if (request->datafd != -1) |
1 | 141 { |
87 | 142 if (close (request->datafd) == -1) |
186 | 143 request->logging_function (gftp_logging_error, request, |
1 | 144 _("Error closing file descriptor: %s\n"), |
145 g_strerror (errno)); | |
58 | 146 request->datafd = -1; |
1 | 147 } |
148 } | |
149 | |
150 | |
58 | 151 static off_t |
152 local_get_file (gftp_request * request, const char *filename, int fd, | |
1 | 153 off_t startsize) |
154 { | |
838 | 155 size_t destlen; |
831 | 156 char *utf8; |
58 | 157 off_t size; |
158 int flags; | |
1 | 159 |
84 | 160 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
161 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
162 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
1 | 163 |
66 | 164 if (fd <= 0) |
1 | 165 { |
7 | 166 flags = O_RDONLY; |
434 | 167 #if defined (_LARGEFILE_SOURCE) && defined (O_LARGEFILE) |
7 | 168 flags |= O_LARGEFILE; |
169 #endif | |
170 | |
845 | 171 utf8 = gftp_filename_from_utf8 (request, filename, &destlen); |
831 | 172 if (utf8 != NULL) |
173 { | |
174 request->datafd = gftp_fd_open (request, utf8, flags, 0); | |
175 g_free (utf8); | |
176 } | |
177 else | |
178 request->datafd = gftp_fd_open (request, filename, flags, 0); | |
179 | |
180 if (request->datafd == -1) | |
182 | 181 return (GFTP_ERETRYABLE); |
1 | 182 } |
183 else | |
184 request->datafd = fd; | |
185 | |
87 | 186 if ((size = lseek (request->datafd, 0, SEEK_END)) == -1) |
1 | 187 { |
186 | 188 request->logging_function (gftp_logging_error, request, |
1 | 189 _("Error: Cannot seek on file %s: %s\n"), |
190 filename, g_strerror (errno)); | |
58 | 191 gftp_disconnect (request); |
84 | 192 return (GFTP_ERETRYABLE); |
1 | 193 } |
194 | |
87 | 195 if (lseek (request->datafd, startsize, SEEK_SET) == -1) |
1 | 196 { |
186 | 197 request->logging_function (gftp_logging_error, request, |
1 | 198 _("Error: Cannot seek on file %s: %s\n"), |
199 filename, g_strerror (errno)); | |
58 | 200 gftp_disconnect (request); |
84 | 201 return (GFTP_ERETRYABLE); |
1 | 202 } |
203 | |
204 return (size); | |
205 } | |
206 | |
207 | |
208 static int | |
58 | 209 local_put_file (gftp_request * request, const char *filename, int fd, |
787 | 210 off_t startsize, off_t totalsize) |
1 | 211 { |
831 | 212 int flags, perms; |
838 | 213 size_t destlen; |
831 | 214 char *utf8; |
1 | 215 |
84 | 216 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
217 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
218 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
1 | 219 |
66 | 220 if (fd <= 0) |
1 | 221 { |
7 | 222 flags = O_WRONLY | O_CREAT; |
223 if (startsize > 0) | |
224 flags |= O_APPEND; | |
434 | 225 #if defined (_LARGEFILE_SOURCE) && defined (O_LARGEFILE) |
7 | 226 flags |= O_LARGEFILE; |
227 #endif | |
228 | |
831 | 229 perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; |
845 | 230 utf8 = gftp_filename_from_utf8 (request, filename, &destlen); |
831 | 231 if (utf8 != NULL) |
232 { | |
233 request->datafd = gftp_fd_open (request, utf8, flags, perms); | |
234 g_free (utf8); | |
235 } | |
236 else | |
237 request->datafd = gftp_fd_open (request, filename, flags, perms); | |
238 | |
239 if (request->datafd == -1) | |
182 | 240 return (GFTP_ERETRYABLE); |
1 | 241 } |
242 else | |
243 request->datafd = fd; | |
244 | |
87 | 245 if (ftruncate (request->datafd, startsize) == -1) |
1 | 246 { |
186 | 247 request->logging_function (gftp_logging_error, request, |
1 | 248 _("Error: Cannot truncate local file %s: %s\n"), |
249 filename, g_strerror (errno)); | |
58 | 250 gftp_disconnect (request); |
84 | 251 return (GFTP_ERETRYABLE); |
1 | 252 } |
253 | |
87 | 254 if (lseek (request->datafd, startsize, SEEK_SET) == -1) |
1 | 255 { |
186 | 256 request->logging_function (gftp_logging_error, request, |
1 | 257 _("Error: Cannot seek on file %s: %s\n"), |
258 filename, g_strerror (errno)); | |
58 | 259 gftp_disconnect (request); |
84 | 260 return (GFTP_ERETRYABLE); |
1 | 261 } |
262 return (0); | |
263 } | |
264 | |
265 | |
266 static int | |
267 local_end_transfer (gftp_request * request) | |
268 { | |
269 local_protocol_data * lpd; | |
270 | |
271 lpd = request->protocol_data; | |
272 if (lpd->dir) | |
273 { | |
274 closedir (lpd->dir); | |
275 lpd->dir = NULL; | |
276 } | |
277 | |
58 | 278 if (request->datafd > 0) |
1 | 279 { |
87 | 280 if (close (request->datafd) == -1) |
186 | 281 request->logging_function (gftp_logging_error, request, |
1 | 282 _("Error closing file descriptor: %s\n"), |
283 g_strerror (errno)); | |
284 | |
58 | 285 request->datafd = -1; |
1 | 286 } |
287 | |
288 return (0); | |
289 } | |
290 | |
291 | |
520 | 292 static int |
787 | 293 local_stat_filename (gftp_request * request, const char *filename, |
294 mode_t * mode, off_t * filesize) | |
500 | 295 { |
296 struct stat st; | |
838 | 297 size_t destlen; |
831 | 298 char *utf8; |
299 int ret; | |
500 | 300 |
845 | 301 utf8 = gftp_filename_from_utf8 (request, filename, &destlen); |
831 | 302 if (utf8 != NULL) |
303 { | |
304 ret = stat (utf8, &st); | |
305 g_free (utf8); | |
306 } | |
307 else | |
308 ret = stat (filename, &st); | |
309 | |
310 if (ret != 0) | |
500 | 311 return (GFTP_ERETRYABLE); |
312 | |
520 | 313 *mode = st.st_mode; |
787 | 314 *filesize = st.st_size; |
315 | |
520 | 316 return (0); |
500 | 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; | |
255 | 324 struct stat st, fst; |
1 | 325 struct dirent *dirp; |
326 char *user, *group; | |
327 struct passwd *pw; | |
328 struct group *gr; | |
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 | |
341 | 332 protocol (see use_threads in gftp_protocols in options.h) */ |
84 | 333 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
334 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
335 g_return_val_if_fail (fle != NULL, GFTP_EFATAL); | |
1 | 336 |
337 lpd = request->protocol_data; | |
87 | 338 |
339 g_return_val_if_fail (lpd != NULL, GFTP_EFATAL); | |
340 | |
1 | 341 memset (fle, 0, sizeof (*fle)); |
342 | |
343 if ((dirp = readdir (lpd->dir)) == NULL) | |
344 { | |
345 closedir (lpd->dir); | |
346 lpd->dir = NULL; | |
274 | 347 return (GFTP_EFATAL); |
1 | 348 } |
349 | |
87 | 350 fle->file = g_strdup (dirp->d_name); |
1 | 351 if (lstat (fle->file, &st) != 0) |
274 | 352 return (GFTP_ERETRYABLE); |
1 | 353 |
255 | 354 if (stat (fle->file, &fst) != 0) |
274 | 355 return (GFTP_ERETRYABLE); |
255 | 356 |
1 | 357 if ((user = g_hash_table_lookup (lpd->userhash, |
358 GUINT_TO_POINTER(st.st_uid))) != NULL) | |
87 | 359 fle->user = g_strdup (user); |
1 | 360 else |
361 { | |
362 if ((pw = getpwuid (st.st_uid)) == NULL) | |
363 fle->user = g_strdup_printf ("%u", st.st_uid); | |
364 else | |
87 | 365 fle->user = g_strdup (pw->pw_name); |
1 | 366 |
87 | 367 user = g_strdup (fle->user); |
1 | 368 g_hash_table_insert (lpd->userhash, GUINT_TO_POINTER (st.st_uid), user); |
369 } | |
370 | |
371 if ((group = g_hash_table_lookup (lpd->grouphash, | |
372 GUINT_TO_POINTER(st.st_gid))) != NULL) | |
87 | 373 fle->group = g_strdup (group); |
1 | 374 else |
375 { | |
376 if ((gr = getgrgid (st.st_gid)) == NULL) | |
377 fle->group = g_strdup_printf ("%u", st.st_gid); | |
378 else | |
87 | 379 fle->group = g_strdup (gr->gr_name); |
1 | 380 |
87 | 381 group = g_strdup (fle->group); |
1 | 382 g_hash_table_insert (lpd->grouphash, GUINT_TO_POINTER (st.st_gid), group); |
383 } | |
384 | |
852 | 385 fle->st_dev = fst.st_dev; |
386 fle->st_ino = fst.st_ino; | |
499 | 387 fle->st_mode = fst.st_mode; |
1 | 388 fle->datetime = st.st_mtime; |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
389 |
499 | 390 if (GFTP_IS_SPECIAL_DEVICE (fle->st_mode)) |
48 | 391 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
|
392 else |
294 | 393 fle->size = fst.st_size; |
1 | 394 |
395 return (1); | |
396 } | |
397 | |
398 | |
399 static int | |
400 local_list_files (gftp_request * request) | |
401 { | |
402 local_protocol_data *lpd; | |
843 | 403 char *dir, *utf8; |
838 | 404 size_t destlen; |
1 | 405 |
84 | 406 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
87 | 407 g_return_val_if_fail (request->directory != NULL, GFTP_EFATAL); |
84 | 408 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); |
87 | 409 |
1 | 410 lpd = request->protocol_data; |
411 | |
87 | 412 g_return_val_if_fail (lpd != NULL, GFTP_EFATAL); |
413 | |
843 | 414 if (request->directory[strlen (request->directory) - 1] != '/') |
415 dir = g_strconcat (request->directory, "/", NULL); | |
416 else | |
417 dir = request->directory; | |
831 | 418 |
845 | 419 utf8 = gftp_filename_from_utf8 (request, dir, &destlen); |
843 | 420 if (utf8 != NULL) |
87 | 421 { |
843 | 422 lpd->dir = opendir (utf8); |
423 g_free (utf8); | |
87 | 424 } |
425 else | |
843 | 426 lpd->dir = opendir (dir); |
1 | 427 |
843 | 428 if (dir != request->directory) |
429 g_free (dir); | |
430 | |
431 if (lpd->dir == NULL) | |
1 | 432 { |
186 | 433 request->logging_function (gftp_logging_error, request, |
1 | 434 _("Could not get local directory listing %s: %s\n"), |
843 | 435 request->directory, g_strerror (errno)); |
436 return (GFTP_ERETRYABLE); | |
1 | 437 } |
831 | 438 else |
843 | 439 return (0); |
1 | 440 } |
441 | |
442 | |
443 static off_t | |
787 | 444 local_get_file_size (gftp_request * request, const char *filename) |
1 | 445 { |
446 struct stat st; | |
838 | 447 size_t destlen; |
831 | 448 char *utf8; |
449 int ret; | |
1 | 450 |
845 | 451 utf8 = gftp_filename_from_utf8 (request, filename, &destlen); |
831 | 452 if (utf8 != NULL) |
1 | 453 { |
831 | 454 ret = stat (utf8, &st); |
455 g_free (utf8); | |
1 | 456 } |
87 | 457 else |
831 | 458 ret = stat (filename, &st); |
459 | |
460 if (ret == -1) | |
461 return (GFTP_ERETRYABLE); | |
462 | |
463 return (st.st_size); | |
1 | 464 } |
465 | |
466 | |
467 static int | |
468 local_rmdir (gftp_request * request, const char *directory) | |
469 { | |
838 | 470 size_t destlen; |
831 | 471 char *utf8; |
472 int ret; | |
473 | |
84 | 474 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
475 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
476 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
1 | 477 |
845 | 478 utf8 = gftp_filename_from_utf8 (request, directory, &destlen); |
831 | 479 if (utf8 != NULL) |
480 { | |
481 ret = rmdir (utf8); | |
482 g_free (utf8); | |
483 } | |
484 else | |
485 ret = rmdir (directory); | |
486 | |
487 if (ret == 0) | |
1 | 488 { |
186 | 489 request->logging_function (gftp_logging_misc, request, |
1 | 490 _("Successfully removed %s\n"), directory); |
491 return (0); | |
492 } | |
493 else | |
494 { | |
186 | 495 request->logging_function (gftp_logging_error, request, |
1 | 496 _("Error: Could not remove directory %s: %s\n"), |
497 directory, g_strerror (errno)); | |
84 | 498 return (GFTP_ERETRYABLE); |
1 | 499 } |
500 } | |
501 | |
502 | |
503 static int | |
504 local_rmfile (gftp_request * request, const char *file) | |
505 { | |
838 | 506 size_t destlen; |
831 | 507 char *utf8; |
508 int ret; | |
509 | |
84 | 510 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
511 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
512 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 513 |
845 | 514 utf8 = gftp_filename_from_utf8 (request, file, &destlen); |
831 | 515 if (utf8 != NULL) |
516 { | |
517 ret = unlink (utf8); | |
518 g_free (utf8); | |
519 } | |
520 else | |
521 ret = unlink (file); | |
522 | |
523 if (ret == 0) | |
1 | 524 { |
186 | 525 request->logging_function (gftp_logging_misc, request, |
1 | 526 _("Successfully removed %s\n"), file); |
527 return (0); | |
528 } | |
529 else | |
530 { | |
186 | 531 request->logging_function (gftp_logging_error, request, |
1 | 532 _("Error: Could not remove file %s: %s\n"), |
533 file, g_strerror (errno)); | |
84 | 534 return (GFTP_ERETRYABLE); |
1 | 535 } |
536 } | |
537 | |
538 | |
539 static int | |
540 local_mkdir (gftp_request * request, const char *directory) | |
541 { | |
831 | 542 int ret, perms; |
838 | 543 size_t destlen; |
831 | 544 char *utf8; |
545 | |
84 | 546 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
547 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
548 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
1 | 549 |
831 | 550 perms = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
551 | |
845 | 552 utf8 = gftp_filename_from_utf8 (request, directory, &destlen); |
831 | 553 if (utf8 != NULL) |
554 { | |
555 ret = mkdir (utf8, perms); | |
556 g_free (utf8); | |
557 } | |
558 else | |
559 ret = mkdir (directory, perms); | |
560 | |
561 if (ret == 0) | |
1 | 562 { |
186 | 563 request->logging_function (gftp_logging_misc, request, |
1 | 564 _("Successfully made directory %s\n"), |
565 directory); | |
566 return (0); | |
567 } | |
568 else | |
569 { | |
186 | 570 request->logging_function (gftp_logging_error, request, |
1 | 571 _("Error: Could not make directory %s: %s\n"), |
572 directory, g_strerror (errno)); | |
84 | 573 return (GFTP_ERETRYABLE); |
1 | 574 } |
575 } | |
576 | |
577 | |
578 static int | |
579 local_rename (gftp_request * request, const char *oldname, | |
580 const char *newname) | |
581 { | |
831 | 582 const char *conv_oldname, *conv_newname; |
583 char *old_utf8, *new_utf8; | |
838 | 584 size_t destlen; |
831 | 585 int ret; |
586 | |
84 | 587 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
588 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
589 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
590 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
1 | 591 |
845 | 592 old_utf8 = gftp_filename_from_utf8 (request, oldname, &destlen); |
831 | 593 conv_oldname = old_utf8 != NULL ? old_utf8 : oldname; |
845 | 594 new_utf8 = gftp_filename_from_utf8 (request, newname, &destlen); |
831 | 595 conv_newname = new_utf8 != NULL ? new_utf8 : newname; |
596 | |
597 if (rename (conv_oldname, conv_newname) == 0) | |
1 | 598 { |
186 | 599 request->logging_function (gftp_logging_misc, request, |
1 | 600 _("Successfully renamed %s to %s\n"), |
601 oldname, newname); | |
831 | 602 ret = 0; |
1 | 603 } |
604 else | |
605 { | |
186 | 606 request->logging_function (gftp_logging_error, request, |
1 | 607 _("Error: Could not rename %s to %s: %s\n"), |
608 oldname, newname, g_strerror (errno)); | |
831 | 609 ret = GFTP_ERETRYABLE; |
1 | 610 } |
831 | 611 |
612 if (old_utf8 != NULL) | |
613 g_free (old_utf8); | |
614 if (new_utf8 != NULL) | |
615 g_free (new_utf8); | |
616 | |
617 return (ret); | |
1 | 618 } |
619 | |
620 | |
621 static int | |
499 | 622 local_chmod (gftp_request * request, const char *file, mode_t mode) |
1 | 623 { |
838 | 624 size_t destlen; |
831 | 625 char *utf8; |
626 int ret; | |
627 | |
84 | 628 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
629 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
630 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 631 |
845 | 632 utf8 = gftp_filename_from_utf8 (request, file, &destlen); |
831 | 633 if (utf8 != NULL) |
634 { | |
635 ret = chmod (utf8, mode); | |
636 g_free (utf8); | |
637 } | |
638 else | |
639 ret = chmod (file, mode); | |
640 | |
641 if (ret == 0) | |
1 | 642 { |
186 | 643 request->logging_function (gftp_logging_misc, request, |
504 | 644 _("Successfully changed mode of %s to %o\n"), |
1 | 645 file, mode); |
646 return (0); | |
647 } | |
648 else | |
649 { | |
186 | 650 request->logging_function (gftp_logging_error, request, |
504 | 651 _("Error: Could not change mode of %s to %o: %s\n"), |
1 | 652 file, mode, g_strerror (errno)); |
84 | 653 return (GFTP_ERETRYABLE); |
1 | 654 } |
655 } | |
656 | |
657 | |
658 static int | |
659 local_set_file_time (gftp_request * request, const char *file, | |
660 time_t datetime) | |
661 { | |
662 struct utimbuf time_buf; | |
838 | 663 size_t destlen; |
831 | 664 char *utf8; |
665 int ret; | |
1 | 666 |
84 | 667 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
668 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
669 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 670 |
516 | 671 time_buf.modtime = datetime; |
672 time_buf.actime = datetime; | |
831 | 673 |
845 | 674 utf8 = gftp_filename_from_utf8 (request, file, &destlen); |
831 | 675 if (utf8 != NULL) |
676 { | |
677 ret = utime (utf8, &time_buf); | |
678 g_free (utf8); | |
679 } | |
680 else | |
681 ret = utime (file, &time_buf); | |
682 | |
683 if (ret == 0) | |
684 { | |
685 request->logging_function (gftp_logging_misc, request, | |
686 _("Successfully changed the time stamp of %s\n"), | |
687 file); | |
688 return (0); | |
689 } | |
690 else | |
691 { | |
692 request->logging_function (gftp_logging_error, request, | |
693 _("Error: Could not change the time stamp of %s: %s\n"), | |
694 file, g_strerror (errno)); | |
695 return (GFTP_ERETRYABLE); | |
696 } | |
1 | 697 } |
698 | |
699 | |
122 | 700 void |
701 local_register_module (void) | |
702 { | |
703 } | |
704 | |
705 | |
173 | 706 int |
48 | 707 local_init (gftp_request * request) |
708 { | |
709 local_protocol_data *lpd; | |
710 | |
173 | 711 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
48 | 712 |
713 request->protonum = GFTP_LOCAL_NUM; | |
714 request->init = local_init; | |
309 | 715 request->copy_param_options = NULL; |
48 | 716 request->destroy = local_destroy; |
168 | 717 request->read_function = gftp_fd_read; |
718 request->write_function = gftp_fd_write; | |
48 | 719 request->connect = local_connect; |
168 | 720 request->post_connect = NULL; |
48 | 721 request->disconnect = local_disconnect; |
722 request->get_file = local_get_file; | |
723 request->put_file = local_put_file; | |
724 request->transfer_file = NULL; | |
725 request->get_next_file_chunk = NULL; | |
726 request->put_next_file_chunk = NULL; | |
727 request->end_transfer = local_end_transfer; | |
728 request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ | |
500 | 729 request->stat_filename = local_stat_filename; |
48 | 730 request->list_files = local_list_files; |
731 request->get_next_file = local_get_next_file; | |
485 | 732 request->get_next_dirlist_line = NULL; |
48 | 733 request->get_file_size = local_get_file_size; |
734 request->chdir = local_chdir; | |
735 request->rmdir = local_rmdir; | |
736 request->rmfile = local_rmfile; | |
737 request->mkdir = local_mkdir; | |
738 request->rename = local_rename; | |
739 request->chmod = local_chmod; | |
740 request->set_file_time = local_set_file_time; | |
741 request->site = NULL; | |
742 request->parse_url = NULL; | |
58 | 743 request->set_config_options = NULL; |
63 | 744 request->swap_socks = NULL; |
48 | 745 request->url_prefix = "file"; |
746 request->need_hostport = 0; | |
553 | 747 request->need_username = 0; |
748 request->need_password = 0; | |
48 | 749 request->use_cache = 0; |
750 request->always_connected = 1; | |
832 | 751 request->use_local_encoding = 1; |
48 | 752 |
753 lpd = g_malloc0 (sizeof (*lpd)); | |
754 request->protocol_data = lpd; | |
852 | 755 lpd->userhash = g_hash_table_new (uint_hash_function, uint_hash_compare); |
756 lpd->grouphash = g_hash_table_new (uint_hash_function, uint_hash_compare); | |
66 | 757 |
758 if (request->hostname != NULL) | |
759 g_free (request->hostname); | |
760 request->hostname = g_strdup (_("local filesystem")); | |
173 | 761 |
177 | 762 return (gftp_set_config_options (request)); |
48 | 763 } |
764 |