Mercurial > gftp.yaz
annotate lib/local.c @ 53:abc00836827f
2002-11-11 Andras Timar <timar@gnome.hu>
* hu.po: Added Hungarian translation by Doome <doome@uhulinux.hu>
Edited by myself...
author | bansz |
---|---|
date | Sun, 10 Nov 2002 23:07:19 +0000 |
parents | e5f6054590b5 |
children | c01d91c10f6c |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* local.c - functions that will use the local system */ | |
3 /* Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org> */ | |
4 /* */ | |
5 /* This program is free software; you can redistribute it and/or modify */ | |
6 /* it under the terms of the GNU General Public License as published by */ | |
7 /* the Free Software Foundation; either version 2 of the License, or */ | |
8 /* (at your option) any later version. */ | |
9 /* */ | |
10 /* This program is distributed in the hope that it will be useful, */ | |
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | |
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | |
13 /* GNU General Public License for more details. */ | |
14 /* */ | |
15 /* You should have received a copy of the GNU General Public License */ | |
16 /* along with this program; if not, write to the Free Software */ | |
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ | |
18 /*****************************************************************************/ | |
19 | |
20 #include "gftp.h" | |
33 | 21 static const char cvsid[] = "$Id$"; |
1 | 22 |
23 typedef struct local_protocol_data_tag | |
24 { | |
25 DIR *dir; | |
26 GHashTable *userhash, *grouphash; | |
27 } local_protocol_data; | |
28 | |
29 | |
48 | 30 static void |
31 local_remove_key (gpointer key, gpointer value, gpointer user_data) | |
1 | 32 { |
48 | 33 g_free (value); |
1 | 34 } |
35 | |
36 | |
37 static void | |
38 local_destroy (gftp_request * request) | |
39 { | |
40 local_protocol_data * lpd; | |
41 | |
42 g_return_if_fail (request != NULL); | |
43 g_return_if_fail (request->protonum == GFTP_LOCAL_NUM); | |
44 | |
45 lpd = request->protocol_data; | |
46 g_hash_table_foreach (lpd->userhash, local_remove_key, NULL); | |
47 g_hash_table_destroy (lpd->userhash); | |
48 g_hash_table_foreach (lpd->grouphash, local_remove_key, NULL); | |
49 g_hash_table_destroy (lpd->grouphash); | |
50 lpd->userhash = lpd->grouphash = NULL; | |
51 } | |
52 | |
53 | |
54 static int | |
55 local_connect (gftp_request * request) | |
56 { | |
57 char tempstr[PATH_MAX]; | |
58 | |
59 g_return_val_if_fail (request != NULL, -2); | |
60 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
61 | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
62 /* Just to simulate that we are actually connected */ |
1 | 63 request->sockfd = (void *) 1; |
64 | |
65 if (request->directory) | |
66 { | |
67 if (chdir (request->directory) != 0) | |
68 { | |
69 request->logging_function (gftp_logging_error, request->user_data, | |
70 _("Could not change local directory to %s: %s\n"), | |
71 request->directory, g_strerror (errno)); | |
72 } | |
73 g_free (request->directory); | |
74 request->directory = NULL; | |
75 } | |
76 | |
77 if (getcwd (tempstr, sizeof (tempstr)) != NULL) | |
78 { | |
79 tempstr[sizeof (tempstr) - 1] = '\0'; | |
80 request->directory = g_malloc (strlen (tempstr) + 1); | |
81 strcpy (request->directory, tempstr); | |
82 } | |
83 else | |
84 request->logging_function (gftp_logging_error, request->user_data, | |
85 _("Could not get current working directory: %s\n"), | |
86 g_strerror (errno)); | |
87 | |
88 return (0); | |
89 } | |
90 | |
91 | |
92 static void | |
93 local_disconnect (gftp_request * request) | |
94 { | |
95 g_return_if_fail (request != NULL); | |
96 g_return_if_fail (request->protonum == GFTP_LOCAL_NUM); | |
97 | |
98 if (request->datafd != NULL) | |
99 { | |
100 if (fclose (request->datafd) < 0) | |
101 request->logging_function (gftp_logging_error, request->user_data, | |
102 _("Error closing file descriptor: %s\n"), | |
103 g_strerror (errno)); | |
104 request->datafd = NULL; | |
105 } | |
106 request->sockfd = NULL; | |
107 } | |
108 | |
109 | |
110 static long | |
111 local_get_file (gftp_request * request, const char *filename, FILE * fd, | |
112 off_t startsize) | |
113 { | |
114 size_t size; | |
7 | 115 int sock, flags; |
1 | 116 |
117 g_return_val_if_fail (request != NULL, -2); | |
118 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
119 g_return_val_if_fail (filename != NULL, -2); | |
120 | |
121 if (fd == NULL) | |
122 { | |
7 | 123 flags = O_RDONLY; |
124 #if defined (_LARGEFILE_SOURCE) | |
125 flags |= O_LARGEFILE; | |
126 #endif | |
127 | |
128 if ((sock = open (filename, flags)) < 0) | |
1 | 129 { |
130 request->logging_function (gftp_logging_error, request->user_data, | |
131 _("Error: Cannot open local file %s: %s\n"), | |
132 filename, g_strerror (errno)); | |
133 return (-2); | |
134 } | |
7 | 135 |
36 | 136 if ((request->datafd = fdopen (sock, "rb")) == NULL) |
7 | 137 { |
138 request->logging_function (gftp_logging_error, request->user_data, | |
139 _("Cannot fdopen() socket for %s: %s\n"), | |
140 filename, g_strerror (errno)); | |
141 close (sock); | |
142 return (-2); | |
143 } | |
1 | 144 } |
145 else | |
146 request->datafd = fd; | |
147 | |
148 if (lseek (fileno (request->datafd), 0, SEEK_END) == -1) | |
149 { | |
150 request->logging_function (gftp_logging_error, request->user_data, | |
151 _("Error: Cannot seek on file %s: %s\n"), | |
152 filename, g_strerror (errno)); | |
153 fclose (request->datafd); | |
154 request->datafd = NULL; | |
155 } | |
156 | |
157 if ((size = ftell (request->datafd)) == -1) | |
158 { | |
159 request->logging_function (gftp_logging_error, request->user_data, | |
160 _("Error: Cannot seek on file %s: %s\n"), | |
161 filename, g_strerror (errno)); | |
162 fclose (request->datafd); | |
163 request->datafd = NULL; | |
164 } | |
165 | |
166 if (lseek (fileno (request->datafd), startsize, SEEK_SET) == -1) | |
167 { | |
168 request->logging_function (gftp_logging_error, request->user_data, | |
169 _("Error: Cannot seek on file %s: %s\n"), | |
170 filename, g_strerror (errno)); | |
171 fclose (request->datafd); | |
172 request->datafd = NULL; | |
173 } | |
174 | |
175 return (size); | |
176 } | |
177 | |
178 | |
179 static int | |
180 local_put_file (gftp_request * request, const char *filename, FILE * fd, | |
181 off_t startsize, off_t totalsize) | |
182 { | |
7 | 183 int sock, flags; |
1 | 184 |
185 g_return_val_if_fail (request != NULL, -2); | |
186 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
187 g_return_val_if_fail (filename != NULL, -2); | |
188 | |
189 if (fd == NULL) | |
190 { | |
7 | 191 flags = O_WRONLY | O_CREAT; |
192 if (startsize > 0) | |
193 flags |= O_APPEND; | |
194 #if defined (_LARGEFILE_SOURCE) | |
195 flags |= O_LARGEFILE; | |
196 #endif | |
197 | |
198 if ((sock = open (filename, flags, S_IRUSR | S_IWUSR)) < 0) | |
1 | 199 { |
200 request->logging_function (gftp_logging_error, request->user_data, | |
201 _("Error: Cannot open local file %s: %s\n"), | |
202 filename, g_strerror (errno)); | |
203 return (-2); | |
204 } | |
205 | |
19 | 206 if ((request->datafd = fdopen (sock, "ab")) == NULL) |
1 | 207 { |
208 request->logging_function (gftp_logging_error, request->user_data, | |
209 _("Cannot fdopen() socket for %s: %s\n"), | |
210 filename, g_strerror (errno)); | |
211 close (sock); | |
212 return (-2); | |
213 } | |
214 } | |
215 else | |
216 request->datafd = fd; | |
217 | |
218 if (ftruncate (fileno (request->datafd), startsize) == -1) | |
219 { | |
220 request->logging_function (gftp_logging_error, request->user_data, | |
221 _("Error: Cannot truncate local file %s: %s\n"), | |
222 filename, g_strerror (errno)); | |
223 fclose (request->datafd); | |
224 request->datafd = NULL; | |
225 return (-2); | |
226 } | |
227 | |
228 if (fseek (request->datafd, startsize, SEEK_SET) == -1) | |
229 { | |
230 request->logging_function (gftp_logging_error, request->user_data, | |
231 _("Error: Cannot seek on file %s: %s\n"), | |
232 filename, g_strerror (errno)); | |
233 fclose (request->datafd); | |
234 request->datafd = NULL; | |
235 return (-2); | |
236 } | |
237 return (0); | |
238 } | |
239 | |
240 | |
241 static int | |
242 local_end_transfer (gftp_request * request) | |
243 { | |
244 local_protocol_data * lpd; | |
245 | |
246 lpd = request->protocol_data; | |
247 if (lpd->dir) | |
248 { | |
249 closedir (lpd->dir); | |
250 lpd->dir = NULL; | |
251 } | |
252 | |
253 if (request->datafd != NULL) | |
254 { | |
255 if (fclose (request->datafd) < 0) | |
256 request->logging_function (gftp_logging_error, request->user_data, | |
257 _("Error closing file descriptor: %s\n"), | |
258 g_strerror (errno)); | |
259 | |
260 request->datafd = NULL; | |
261 } | |
262 | |
263 return (0); | |
264 } | |
265 | |
266 | |
48 | 267 static char * |
268 make_text_mode (gftp_file * fle, mode_t mode) | |
269 { | |
270 char *str; | |
271 | |
272 str = g_malloc0 (11); | |
273 | |
274 str[0] = '?'; | |
275 if (S_ISREG (mode)) | |
276 str[0] = '-'; | |
277 | |
278 if (S_ISLNK (mode)) | |
279 { | |
280 fle->islink = 1; | |
281 str[0] = 'l'; | |
282 } | |
283 | |
284 if (S_ISBLK (mode)) | |
285 { | |
286 fle->isblock = 1; | |
287 str[0] = 'b'; | |
288 } | |
289 | |
290 if (S_ISCHR (mode)) | |
291 { | |
292 fle->ischar = 1; | |
293 str[0] = 'c'; | |
294 } | |
295 | |
296 if (S_ISFIFO (mode)) | |
297 { | |
298 fle->isfifo = 1; | |
299 str[0] = 'p'; | |
300 } | |
301 | |
302 if (S_ISSOCK (mode)) | |
303 { | |
304 fle->issocket = 1; | |
305 str[0] = 's'; | |
306 } | |
307 | |
308 if (S_ISDIR (mode)) | |
309 { | |
310 fle->isdir = 1; | |
311 str[0] = 'd'; | |
312 } | |
313 | |
314 str[1] = mode & S_IRUSR ? 'r' : '-'; | |
315 str[2] = mode & S_IWUSR ? 'w' : '-'; | |
316 | |
317 if ((mode & S_ISUID) && (mode & S_IXUSR)) | |
318 str[3] = 's'; | |
319 else if (mode & S_ISUID) | |
320 str[3] = 'S'; | |
321 else if (mode & S_IXUSR) | |
322 str[3] = 'x'; | |
323 else | |
324 str[3] = '-'; | |
325 | |
326 str[4] = mode & S_IRGRP ? 'r' : '-'; | |
327 str[5] = mode & S_IWGRP ? 'w' : '-'; | |
328 | |
329 if ((mode & S_ISGID) && (mode & S_IXGRP)) | |
330 str[6] = 's'; | |
331 else if (mode & S_ISGID) | |
332 str[6] = 'S'; | |
333 else if (mode & S_IXGRP) | |
334 str[6] = 'x'; | |
335 else | |
336 str[6] = '-'; | |
337 | |
338 str[7] = mode & S_IROTH ? 'r' : '-'; | |
339 str[8] = mode & S_IWOTH ? 'w' : '-'; | |
340 | |
341 if ((mode & S_ISVTX) && (mode & S_IXOTH)) | |
342 str[9] = 't'; | |
343 else if (mode & S_ISVTX) | |
344 str[9] = 'T'; | |
345 else if (mode & S_IXOTH) | |
346 str[9] = 'x'; | |
347 else | |
348 str[9] = '-'; | |
349 return (str); | |
350 } | |
351 | |
352 | |
1 | 353 static int |
354 local_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd) | |
355 { | |
356 local_protocol_data * lpd; | |
357 struct dirent *dirp; | |
358 char *user, *group; | |
359 struct passwd *pw; | |
360 struct group *gr; | |
361 struct stat st; | |
362 | |
363 /* the struct passwd and struct group are not thread safe. But, | |
364 we're ok here because I have threading turned off for the local | |
365 protocol (see use_threads in local_init above) */ | |
366 g_return_val_if_fail (request != NULL, -2); | |
367 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
368 g_return_val_if_fail (fle != NULL, -2); | |
369 | |
370 lpd = request->protocol_data; | |
371 memset (fle, 0, sizeof (*fle)); | |
372 | |
373 if ((dirp = readdir (lpd->dir)) == NULL) | |
374 { | |
375 closedir (lpd->dir); | |
376 lpd->dir = NULL; | |
377 return (-2); | |
378 } | |
379 | |
380 fle->file = g_malloc (strlen (dirp->d_name) + 1); | |
381 strcpy (fle->file, dirp->d_name); | |
382 if (lstat (fle->file, &st) != 0) | |
383 { | |
384 closedir (lpd->dir); | |
385 lpd->dir = NULL; | |
386 return (-2); | |
387 } | |
388 | |
389 if ((user = g_hash_table_lookup (lpd->userhash, | |
390 GUINT_TO_POINTER(st.st_uid))) != NULL) | |
391 { | |
392 fle->user = g_malloc (strlen (user) + 1); | |
393 strcpy (fle->user, user); | |
394 } | |
395 else | |
396 { | |
397 if ((pw = getpwuid (st.st_uid)) == NULL) | |
398 fle->user = g_strdup_printf ("%u", st.st_uid); | |
399 else | |
400 { | |
401 fle->user = g_malloc (strlen (pw->pw_name) + 1); | |
402 strcpy (fle->user, pw->pw_name); | |
403 } | |
404 | |
405 user = g_malloc (strlen (fle->user) + 1); | |
406 strcpy (user, fle->user); | |
407 g_hash_table_insert (lpd->userhash, GUINT_TO_POINTER (st.st_uid), user); | |
408 } | |
409 | |
410 if ((group = g_hash_table_lookup (lpd->grouphash, | |
411 GUINT_TO_POINTER(st.st_gid))) != NULL) | |
412 { | |
413 fle->group = g_malloc (strlen (group) + 1); | |
414 strcpy (fle->group, group); | |
415 } | |
416 else | |
417 { | |
418 if ((gr = getgrgid (st.st_gid)) == NULL) | |
419 fle->group = g_strdup_printf ("%u", st.st_gid); | |
420 else | |
421 { | |
422 fle->group = g_malloc (strlen (gr->gr_name) + 1); | |
423 strcpy (fle->group, gr->gr_name); | |
424 } | |
425 | |
426 group = g_malloc (strlen (fle->group) + 1); | |
427 strcpy (group, fle->group); | |
428 g_hash_table_insert (lpd->grouphash, GUINT_TO_POINTER (st.st_gid), group); | |
429 } | |
430 | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
431 fle->attribs = make_text_mode (fle, st.st_mode); |
1 | 432 fle->datetime = st.st_mtime; |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
433 |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
434 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
|
435 fle->attribs[0] == 'c')) |
48 | 436 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
|
437 else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
438 fle->size = st.st_size; |
1 | 439 |
440 if (*fle->attribs == 'd') | |
441 fle->isdir = 1; | |
442 if (*fle->attribs == 'l') | |
443 fle->islink = 1; | |
444 if (strchr (fle->attribs, 'x') != NULL && !fle->isdir && !fle->islink) | |
445 fle->isexe = 1; | |
446 if (*fle->attribs == 'b') | |
447 fle->isblock = 1; | |
448 if (*fle->attribs == 'c') | |
449 fle->ischar = 1; | |
450 if (*fle->attribs == 's') | |
451 fle->issocket = 1; | |
452 if (*fle->attribs == 'p') | |
453 fle->isfifo = 1; | |
454 return (1); | |
455 } | |
456 | |
457 | |
458 static int | |
459 local_list_files (gftp_request * request) | |
460 { | |
461 local_protocol_data *lpd; | |
462 char *tempstr; | |
463 | |
464 g_return_val_if_fail (request != NULL, -2); | |
465 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
466 lpd = request->protocol_data; | |
467 | |
468 tempstr = g_strconcat (request->directory, "/", NULL); | |
469 | |
470 if ((lpd->dir = opendir (tempstr)) == NULL) | |
471 { | |
472 request->logging_function (gftp_logging_error, request->user_data, | |
473 _("Could not get local directory listing %s: %s\n"), | |
474 tempstr, g_strerror (errno)); | |
475 g_free (tempstr); | |
476 return (-1); | |
477 } | |
478 | |
479 g_free (tempstr); | |
480 return (0); | |
481 } | |
482 | |
483 | |
484 static off_t | |
485 local_get_file_size (gftp_request * request, const char *filename) | |
486 { | |
487 struct stat st; | |
488 | |
489 if (stat (filename, &st) == -1) | |
490 return (-1); | |
491 return (st.st_size); | |
492 } | |
493 | |
494 | |
495 static int | |
496 local_chdir (gftp_request * request, const char *directory) | |
497 { | |
498 char tempstr[255]; | |
499 | |
500 g_return_val_if_fail (request != NULL, -2); | |
501 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
502 g_return_val_if_fail (directory != NULL, -2); | |
503 | |
504 if (chdir (directory) == 0) | |
505 { | |
506 request->logging_function (gftp_logging_error, request->user_data, | |
507 _("Successfully changed local directory to %s\n"), | |
508 directory); | |
509 if (request->directory != directory) | |
510 { | |
511 if (getcwd (tempstr, sizeof (tempstr)) == NULL) | |
512 { | |
513 request->logging_function (gftp_logging_error, request->user_data, | |
514 _("Could not get current working directory: %s\n"), | |
515 g_strerror (errno)); | |
516 return (-1); | |
517 } | |
518 if (request->directory) | |
519 g_free (request->directory); | |
520 request->directory = g_malloc (strlen (tempstr) + 1); | |
521 strcpy (request->directory, tempstr); | |
522 } | |
523 return (0); | |
524 } | |
525 request->logging_function (gftp_logging_error, request->user_data, | |
526 _("Could not change local directory to %s: %s\n"), | |
527 directory, g_strerror (errno)); | |
528 return (-1); | |
529 } | |
530 | |
531 | |
532 static int | |
533 local_rmdir (gftp_request * request, const char *directory) | |
534 { | |
535 g_return_val_if_fail (request != NULL, -2); | |
536 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
537 g_return_val_if_fail (directory != NULL, -2); | |
538 | |
539 if (rmdir (directory) == 0) | |
540 { | |
541 request->logging_function (gftp_logging_error, request->user_data, | |
542 _("Successfully removed %s\n"), directory); | |
543 return (0); | |
544 } | |
545 else | |
546 { | |
547 request->logging_function (gftp_logging_error, request->user_data, | |
548 _("Error: Could not remove directory %s: %s\n"), | |
549 directory, g_strerror (errno)); | |
550 return (-1); | |
551 } | |
552 } | |
553 | |
554 | |
555 static int | |
556 local_rmfile (gftp_request * request, const char *file) | |
557 { | |
558 g_return_val_if_fail (request != NULL, -2); | |
559 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
560 g_return_val_if_fail (file != NULL, -2); | |
561 | |
562 if (unlink (file) == 0) | |
563 { | |
564 request->logging_function (gftp_logging_error, request->user_data, | |
565 _("Successfully removed %s\n"), file); | |
566 return (0); | |
567 } | |
568 else | |
569 { | |
570 request->logging_function (gftp_logging_error, request->user_data, | |
571 _("Error: Could not remove file %s: %s\n"), | |
572 file, g_strerror (errno)); | |
573 return (-1); | |
574 } | |
575 } | |
576 | |
577 | |
578 static int | |
579 local_mkdir (gftp_request * request, const char *directory) | |
580 { | |
581 g_return_val_if_fail (request != NULL, -2); | |
582 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
583 g_return_val_if_fail (directory != NULL, -2); | |
584 | |
585 if (mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) | |
586 { | |
587 request->logging_function (gftp_logging_error, request->user_data, | |
588 _("Successfully made directory %s\n"), | |
589 directory); | |
590 return (0); | |
591 } | |
592 else | |
593 { | |
594 request->logging_function (gftp_logging_error, request->user_data, | |
595 _("Error: Could not make directory %s: %s\n"), | |
596 directory, g_strerror (errno)); | |
597 return (-1); | |
598 } | |
599 } | |
600 | |
601 | |
602 static int | |
603 local_rename (gftp_request * request, const char *oldname, | |
604 const char *newname) | |
605 { | |
606 g_return_val_if_fail (request != NULL, -2); | |
607 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
608 g_return_val_if_fail (oldname != NULL, -2); | |
609 g_return_val_if_fail (newname != NULL, -2); | |
610 | |
611 if (rename (oldname, newname) == 0) | |
612 { | |
613 request->logging_function (gftp_logging_error, request->user_data, | |
614 _("Successfully renamed %s to %s\n"), | |
615 oldname, newname); | |
616 return (0); | |
617 } | |
618 else | |
619 { | |
620 request->logging_function (gftp_logging_error, request->user_data, | |
621 _("Error: Could not rename %s to %s: %s\n"), | |
622 oldname, newname, g_strerror (errno)); | |
623 return (-1); | |
624 } | |
625 } | |
626 | |
627 | |
628 static int | |
629 local_chmod (gftp_request * request, const char *file, int mode) | |
630 { | |
631 char buf[10]; | |
632 int newmode; | |
633 | |
634 g_return_val_if_fail (request != NULL, -2); | |
635 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
636 g_return_val_if_fail (file != NULL, -2); | |
637 | |
638 g_snprintf (buf, sizeof (buf), "%d", mode); | |
639 newmode = strtol (buf, NULL, 8); | |
640 | |
641 if (chmod (file, newmode) == 0) | |
642 { | |
643 request->logging_function (gftp_logging_error, request->user_data, | |
644 _("Successfully changed mode of %s to %d\n"), | |
645 file, mode); | |
646 return (0); | |
647 } | |
648 else | |
649 { | |
650 request->logging_function (gftp_logging_error, request->user_data, | |
651 _("Error: Could not change mode of %s to %d: %s\n"), | |
652 file, mode, g_strerror (errno)); | |
653 return (-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; | |
663 | |
664 g_return_val_if_fail (request != NULL, -2); | |
665 g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2); | |
666 g_return_val_if_fail (file != NULL, -2); | |
667 | |
668 time_buf.modtime = time_buf.actime = datetime; | |
669 return (utime (file, &time_buf)); | |
670 } | |
671 | |
672 | |
673 static gint | |
674 hash_compare (gconstpointer path1, gconstpointer path2) | |
675 { | |
676 return (GPOINTER_TO_UINT (path1) == GPOINTER_TO_UINT (path2)); | |
677 } | |
678 | |
679 | |
680 static guint | |
681 hash_function (gconstpointer key) | |
682 { | |
683 return (GPOINTER_TO_UINT (key)); | |
684 } | |
685 | |
48 | 686 |
687 void | |
688 local_init (gftp_request * request) | |
689 { | |
690 local_protocol_data *lpd; | |
691 | |
692 g_return_if_fail (request != NULL); | |
693 | |
694 request->protonum = GFTP_LOCAL_NUM; | |
695 request->init = local_init; | |
696 request->destroy = local_destroy; | |
697 request->connect = local_connect; | |
698 request->disconnect = local_disconnect; | |
699 request->get_file = local_get_file; | |
700 request->put_file = local_put_file; | |
701 request->transfer_file = NULL; | |
702 request->get_next_file_chunk = NULL; | |
703 request->put_next_file_chunk = NULL; | |
704 request->end_transfer = local_end_transfer; | |
705 request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ | |
706 request->list_files = local_list_files; | |
707 request->get_next_file = local_get_next_file; | |
708 request->set_data_type = NULL; | |
709 request->get_file_size = local_get_file_size; | |
710 request->chdir = local_chdir; | |
711 request->rmdir = local_rmdir; | |
712 request->rmfile = local_rmfile; | |
713 request->mkdir = local_mkdir; | |
714 request->rename = local_rename; | |
715 request->chmod = local_chmod; | |
716 request->set_file_time = local_set_file_time; | |
717 request->site = NULL; | |
718 request->parse_url = NULL; | |
719 request->url_prefix = "file"; | |
720 request->protocol_name = "Local"; | |
721 request->need_hostport = 0; | |
722 request->need_userpass = 0; | |
723 request->use_cache = 0; | |
724 request->use_threads = 0; | |
725 request->always_connected = 1; | |
726 gftp_set_config_options (request); | |
727 | |
728 lpd = g_malloc0 (sizeof (*lpd)); | |
729 request->protocol_data = lpd; | |
730 lpd->userhash = g_hash_table_new (hash_function, hash_compare); | |
731 lpd->grouphash = g_hash_table_new (hash_function, hash_compare); | |
732 } | |
733 |