Mercurial > gftp.yaz
annotate lib/local.c @ 263:589f9c8c279b
2003-08-25 updated ja.po. T.Aihana <aihana@gnome.gr.jp>
author | aihana |
---|---|
date | Mon, 25 Aug 2003 11:16:03 +0000 |
parents | 2ad324cf4930 |
children | 4610d25d4abb |
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 | |
244 | 170 if ((request->datafd = gftp_fd_open (request, filename, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) |
182 | 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; | |
255 | 295 struct stat st, fst; |
1 | 296 struct dirent *dirp; |
297 char *user, *group; | |
298 struct passwd *pw; | |
299 struct group *gr; | |
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 | |
255 | 329 if (stat (fle->file, &fst) != 0) |
330 { | |
331 closedir (lpd->dir); | |
332 lpd->dir = NULL; | |
333 return (GFTP_ERETRYABLE); | |
334 } | |
335 | |
1 | 336 if ((user = g_hash_table_lookup (lpd->userhash, |
337 GUINT_TO_POINTER(st.st_uid))) != NULL) | |
87 | 338 fle->user = g_strdup (user); |
1 | 339 else |
340 { | |
341 if ((pw = getpwuid (st.st_uid)) == NULL) | |
342 fle->user = g_strdup_printf ("%u", st.st_uid); | |
343 else | |
87 | 344 fle->user = g_strdup (pw->pw_name); |
1 | 345 |
87 | 346 user = g_strdup (fle->user); |
1 | 347 g_hash_table_insert (lpd->userhash, GUINT_TO_POINTER (st.st_uid), user); |
348 } | |
349 | |
350 if ((group = g_hash_table_lookup (lpd->grouphash, | |
351 GUINT_TO_POINTER(st.st_gid))) != NULL) | |
87 | 352 fle->group = g_strdup (group); |
1 | 353 else |
354 { | |
355 if ((gr = getgrgid (st.st_gid)) == NULL) | |
356 fle->group = g_strdup_printf ("%u", st.st_gid); | |
357 else | |
87 | 358 fle->group = g_strdup (gr->gr_name); |
1 | 359 |
87 | 360 group = g_strdup (fle->group); |
1 | 361 g_hash_table_insert (lpd->grouphash, GUINT_TO_POINTER (st.st_gid), group); |
362 } | |
363 | |
87 | 364 fle->attribs = make_text_mode (st.st_mode); |
1 | 365 fle->datetime = st.st_mtime; |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
366 |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
367 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
|
368 fle->attribs[0] == 'c')) |
48 | 369 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
|
370 else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
371 fle->size = st.st_size; |
1 | 372 |
255 | 373 fle->isdir = S_ISDIR (fst.st_mode); |
91 | 374 fle->islink = S_ISLNK (st.st_mode); |
255 | 375 fle->isexe = (fst.st_mode & S_IXUSR) || |
376 (fst.st_mode & S_IXGRP) || | |
377 (fst.st_mode & S_IXOTH); | |
87 | 378 |
1 | 379 return (1); |
380 } | |
381 | |
382 | |
383 static int | |
384 local_list_files (gftp_request * request) | |
385 { | |
386 local_protocol_data *lpd; | |
387 char *tempstr; | |
87 | 388 int freeit; |
1 | 389 |
84 | 390 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
87 | 391 g_return_val_if_fail (request->directory != NULL, GFTP_EFATAL); |
84 | 392 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); |
87 | 393 |
1 | 394 lpd = request->protocol_data; |
395 | |
87 | 396 g_return_val_if_fail (lpd != NULL, GFTP_EFATAL); |
397 | |
398 if (request->directory[strlen (request->directory) - 1] != '/') | |
399 { | |
400 tempstr = g_strconcat (request->directory, "/", NULL); | |
401 freeit = 1; | |
402 } | |
403 else | |
404 { | |
405 tempstr = request->directory; | |
406 freeit = 0; | |
407 } | |
1 | 408 |
409 if ((lpd->dir = opendir (tempstr)) == NULL) | |
410 { | |
186 | 411 request->logging_function (gftp_logging_error, request, |
1 | 412 _("Could not get local directory listing %s: %s\n"), |
413 tempstr, g_strerror (errno)); | |
87 | 414 if (freeit) |
415 g_free (tempstr); | |
84 | 416 return (GFTP_ERETRYABLE); |
1 | 417 } |
418 | |
87 | 419 if (freeit) |
420 g_free (tempstr); | |
421 | |
1 | 422 return (0); |
423 } | |
424 | |
425 | |
426 static off_t | |
427 local_get_file_size (gftp_request * request, const char *filename) | |
428 { | |
429 struct stat st; | |
430 | |
87 | 431 if (stat (filename, &st) == -1) |
84 | 432 return (GFTP_ERETRYABLE); |
1 | 433 return (st.st_size); |
434 } | |
435 | |
436 | |
437 static int | |
438 local_chdir (gftp_request * request, const char *directory) | |
439 { | |
440 char tempstr[255]; | |
441 | |
84 | 442 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
443 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
444 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
1 | 445 |
446 if (chdir (directory) == 0) | |
447 { | |
186 | 448 request->logging_function (gftp_logging_misc, request, |
1 | 449 _("Successfully changed local directory to %s\n"), |
450 directory); | |
136 | 451 |
253 | 452 if (request->directory != directory) |
1 | 453 { |
253 | 454 if (getcwd (tempstr, sizeof (tempstr)) == NULL) |
455 { | |
456 request->logging_function (gftp_logging_error, request, | |
457 _("Could not get current working directory: %s\n"), | |
458 g_strerror (errno)); | |
459 return (GFTP_ERETRYABLE); | |
460 } | |
461 | |
462 if (request->directory) | |
463 g_free (request->directory); | |
464 request->directory = g_strdup (tempstr); | |
136 | 465 } |
87 | 466 |
1 | 467 return (0); |
468 } | |
87 | 469 else |
470 { | |
186 | 471 request->logging_function (gftp_logging_error, request, |
87 | 472 _("Could not change local directory to %s: %s\n"), |
473 directory, g_strerror (errno)); | |
474 return (GFTP_ERETRYABLE); | |
475 } | |
1 | 476 } |
477 | |
478 | |
479 static int | |
480 local_rmdir (gftp_request * request, const char *directory) | |
481 { | |
84 | 482 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
483 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
484 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
1 | 485 |
486 if (rmdir (directory) == 0) | |
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 { | |
84 | 505 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
506 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
507 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 508 |
509 if (unlink (file) == 0) | |
510 { | |
186 | 511 request->logging_function (gftp_logging_misc, request, |
1 | 512 _("Successfully removed %s\n"), file); |
513 return (0); | |
514 } | |
515 else | |
516 { | |
186 | 517 request->logging_function (gftp_logging_error, request, |
1 | 518 _("Error: Could not remove file %s: %s\n"), |
519 file, g_strerror (errno)); | |
84 | 520 return (GFTP_ERETRYABLE); |
1 | 521 } |
522 } | |
523 | |
524 | |
525 static int | |
526 local_mkdir (gftp_request * request, const char *directory) | |
527 { | |
84 | 528 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
529 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
530 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
1 | 531 |
532 if (mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) | |
533 { | |
186 | 534 request->logging_function (gftp_logging_misc, request, |
1 | 535 _("Successfully made directory %s\n"), |
536 directory); | |
537 return (0); | |
538 } | |
539 else | |
540 { | |
186 | 541 request->logging_function (gftp_logging_error, request, |
1 | 542 _("Error: Could not make directory %s: %s\n"), |
543 directory, g_strerror (errno)); | |
84 | 544 return (GFTP_ERETRYABLE); |
1 | 545 } |
546 } | |
547 | |
548 | |
549 static int | |
550 local_rename (gftp_request * request, const char *oldname, | |
551 const char *newname) | |
552 { | |
84 | 553 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
554 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
555 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
556 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
1 | 557 |
558 if (rename (oldname, newname) == 0) | |
559 { | |
186 | 560 request->logging_function (gftp_logging_misc, request, |
1 | 561 _("Successfully renamed %s to %s\n"), |
562 oldname, newname); | |
563 return (0); | |
564 } | |
565 else | |
566 { | |
186 | 567 request->logging_function (gftp_logging_error, request, |
1 | 568 _("Error: Could not rename %s to %s: %s\n"), |
569 oldname, newname, g_strerror (errno)); | |
84 | 570 return (GFTP_ERETRYABLE); |
1 | 571 } |
572 } | |
573 | |
574 | |
575 static int | |
576 local_chmod (gftp_request * request, const char *file, int mode) | |
577 { | |
578 char buf[10]; | |
579 int newmode; | |
580 | |
84 | 581 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
582 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
583 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 584 |
585 g_snprintf (buf, sizeof (buf), "%d", mode); | |
586 newmode = strtol (buf, NULL, 8); | |
587 | |
588 if (chmod (file, newmode) == 0) | |
589 { | |
186 | 590 request->logging_function (gftp_logging_misc, request, |
1 | 591 _("Successfully changed mode of %s to %d\n"), |
592 file, mode); | |
593 return (0); | |
594 } | |
595 else | |
596 { | |
186 | 597 request->logging_function (gftp_logging_error, request, |
1 | 598 _("Error: Could not change mode of %s to %d: %s\n"), |
599 file, mode, g_strerror (errno)); | |
84 | 600 return (GFTP_ERETRYABLE); |
1 | 601 } |
602 } | |
603 | |
604 | |
605 static int | |
606 local_set_file_time (gftp_request * request, const char *file, | |
607 time_t datetime) | |
608 { | |
609 struct utimbuf time_buf; | |
610 | |
84 | 611 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
612 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); | |
613 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
1 | 614 |
615 time_buf.modtime = time_buf.actime = datetime; | |
84 | 616 return (utime (file, &time_buf) == 0 ? 0 : GFTP_ERETRYABLE); |
1 | 617 } |
618 | |
619 | |
620 static gint | |
621 hash_compare (gconstpointer path1, gconstpointer path2) | |
622 { | |
623 return (GPOINTER_TO_UINT (path1) == GPOINTER_TO_UINT (path2)); | |
624 } | |
625 | |
626 | |
627 static guint | |
628 hash_function (gconstpointer key) | |
629 { | |
630 return (GPOINTER_TO_UINT (key)); | |
631 } | |
632 | |
48 | 633 |
122 | 634 void |
635 local_register_module (void) | |
636 { | |
637 } | |
638 | |
639 | |
173 | 640 int |
48 | 641 local_init (gftp_request * request) |
642 { | |
643 local_protocol_data *lpd; | |
644 | |
173 | 645 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
48 | 646 |
647 request->protonum = GFTP_LOCAL_NUM; | |
648 request->init = local_init; | |
649 request->destroy = local_destroy; | |
168 | 650 request->read_function = gftp_fd_read; |
651 request->write_function = gftp_fd_write; | |
48 | 652 request->connect = local_connect; |
168 | 653 request->post_connect = NULL; |
48 | 654 request->disconnect = local_disconnect; |
655 request->get_file = local_get_file; | |
656 request->put_file = local_put_file; | |
657 request->transfer_file = NULL; | |
658 request->get_next_file_chunk = NULL; | |
659 request->put_next_file_chunk = NULL; | |
660 request->end_transfer = local_end_transfer; | |
661 request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ | |
662 request->list_files = local_list_files; | |
663 request->get_next_file = local_get_next_file; | |
664 request->get_file_size = local_get_file_size; | |
665 request->chdir = local_chdir; | |
666 request->rmdir = local_rmdir; | |
667 request->rmfile = local_rmfile; | |
668 request->mkdir = local_mkdir; | |
669 request->rename = local_rename; | |
670 request->chmod = local_chmod; | |
671 request->set_file_time = local_set_file_time; | |
672 request->site = NULL; | |
673 request->parse_url = NULL; | |
58 | 674 request->set_config_options = NULL; |
63 | 675 request->swap_socks = NULL; |
48 | 676 request->url_prefix = "file"; |
677 request->need_hostport = 0; | |
678 request->need_userpass = 0; | |
679 request->use_cache = 0; | |
680 request->use_threads = 0; | |
681 request->always_connected = 1; | |
682 | |
683 lpd = g_malloc0 (sizeof (*lpd)); | |
684 request->protocol_data = lpd; | |
685 lpd->userhash = g_hash_table_new (hash_function, hash_compare); | |
686 lpd->grouphash = g_hash_table_new (hash_function, hash_compare); | |
66 | 687 |
688 if (request->hostname != NULL) | |
689 g_free (request->hostname); | |
690 request->hostname = g_strdup (_("local filesystem")); | |
173 | 691 |
177 | 692 return (gftp_set_config_options (request)); |
48 | 693 } |
694 |