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