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