4 * Copyright (C) 2001, the ROX-Filer team.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place, Suite 330, Boston, MA 02111-1307 USA
21 /* diritem.c - get details about files */
23 /* Don't load icons larger than 400K (this is rather excessive, basically
24 * we just want to stop people crashing the filer with huge icons).
26 #define MAX_ICON_SIZE (400 * 1024)
39 #include "gui_support.h"
43 #include "usericons.h"
46 static gboolean o_ignore_exec
= FALSE
;
48 /* Static prototypes */
49 static void set_ignore_exec(guchar
*new);
52 /****************************************************************
53 * EXTERNAL INTERFACE *
54 ****************************************************************/
56 void diritem_init(void)
58 option_add_int("display_ignore_exec", o_ignore_exec
, set_ignore_exec
);
63 /* Bring this item's structure uptodate.
64 * Use diritem_stat() instead the first time to initialise the item.
66 void diritem_restat(guchar
*path
, DirItem
*item
, gboolean make_thumb
)
72 pixmap_unref(item
->image
);
76 item
->mime_type
= NULL
;
78 if (mc_lstat(path
, &info
) == -1)
80 item
->lstat_errno
= errno
;
81 item
->base_type
= TYPE_ERROR
;
84 item
->mtime
= item
->ctime
= item
->atime
= 0;
85 item
->uid
= (uid_t
) -1;
86 item
->gid
= (gid_t
) -1;
90 item
->lstat_errno
= 0;
91 item
->size
= info
.st_size
;
92 item
->mode
= info
.st_mode
;
93 item
->atime
= info
.st_atime
;
94 item
->ctime
= info
.st_ctime
;
95 item
->mtime
= info
.st_mtime
;
96 item
->uid
= info
.st_uid
;
97 item
->gid
= info
.st_gid
;
99 if (S_ISLNK(info
.st_mode
))
101 if (mc_stat(path
, &info
))
102 item
->base_type
= TYPE_ERROR
;
105 mode_to_base_type(info
.st_mode
);
107 item
->flags
|= ITEM_FLAG_SYMLINK
;
111 item
->base_type
= mode_to_base_type(info
.st_mode
);
113 if (item
->base_type
== TYPE_DIRECTORY
)
115 if (mount_is_mounted(path
))
116 item
->flags
|= ITEM_FLAG_MOUNT_POINT
118 else if (g_hash_table_lookup(fstab_mounts
,
120 item
->flags
|= ITEM_FLAG_MOUNT_POINT
;
125 if (item
->base_type
== TYPE_DIRECTORY
&&
126 !(item
->flags
& ITEM_FLAG_MOUNT_POINT
))
128 uid_t uid
= info
.st_uid
;
133 check_globicon(path
, item
);
137 * - If it contains a .DirIcon.png then that's the icon
138 * - If it contains an AppRun then it's an application
139 * - If it contains an AppRun but no .DirIcon then try to
140 * use AppIcon.xpm as the icon.
142 * .DirIcon.png and AppRun must have the same owner as the
143 * directory itself, to prevent abuse of /tmp, etc.
144 * For symlinks, we want the symlink's owner.
147 path_len
= strlen(path
);
148 /* (sizeof(string) includes \0) */
149 tmp
= g_malloc(path_len
+ sizeof("/.DirIcon.png"));
151 /* Try to find .DirIcon.png... */
152 sprintf(tmp
, "%s/%s", path
, ".DirIcon.png");
153 if (mc_lstat(tmp
, &info
) == 0 && info
.st_uid
== uid
)
155 if (info
.st_size
> MAX_ICON_SIZE
||
156 !S_ISREG(info
.st_mode
))
158 /* Don't let nasty files cause us trouble */
159 /* (Note: slight race here) */
160 item
->image
= im_appdir
;
161 pixmap_ref(item
->image
);
164 item
->image
= g_fscache_lookup(pixmap_cache
,
168 /* Try to find AppRun... */
169 strcpy(tmp
+ path_len
+ 1, "AppRun");
170 if (mc_lstat(tmp
, &info
) == 0 && info
.st_uid
== uid
&&
171 info
.st_mode
& (S_IXUSR
| S_IXGRP
| S_IXOTH
))
172 item
->flags
|= ITEM_FLAG_APPDIR
;
174 /* Are we still missing an icon for this app? */
175 if (item
->flags
& ITEM_FLAG_APPDIR
&& !item
->image
)
177 strcpy(tmp
+ path_len
+ 4, "Icon.xpm");
179 if (mc_lstat(tmp
, &icon
) == 0 &&
180 S_ISREG(icon
.st_mode
) &&
181 icon
.st_size
<= MAX_ICON_SIZE
)
183 item
->image
= g_fscache_lookup(pixmap_cache
,
189 item
->image
= im_appdir
;
190 pixmap_ref(item
->image
);
196 else if (item
->base_type
== TYPE_FILE
)
198 /* Type determined from path before checking for executables
199 * because some mounts show everything as executable and we
200 * still want to use the file name to set the mime type.
202 item
->mime_type
= type_from_path(path
);
204 /* Note: for symlinks we need the mode of the target */
205 if (info
.st_mode
& (S_IXUSR
| S_IXGRP
| S_IXOTH
))
207 /* Note that the flag is set for ALL executable
208 * files, but the mime_type is only special_exec
209 * if the file doesn't have a known extension when
210 * that option is in force.
212 item
->flags
|= ITEM_FLAG_EXEC_FILE
;
215 item
->mime_type
= &special_exec
;
218 if (!item
->mime_type
)
219 item
->mime_type
= item
->flags
& ITEM_FLAG_EXEC_FILE
224 item
->image
= g_fscache_lookup(pixmap_cache
, path
);
226 item
->image
= g_fscache_lookup_full(pixmap_cache
,
228 FSCACHE_LOOKUP_ONLY_NEW
);
230 check_globicon(path
, item
);
233 check_globicon(path
, item
);
236 if (!item
->mime_type
)
237 item
->mime_type
= mime_type_from_base_type(item
->base_type
);
241 if (item
->base_type
== TYPE_ERROR
)
243 item
->image
= im_error
;
244 pixmap_ref(im_error
);
247 item
->image
= type_to_icon(item
->mime_type
);
251 /* Fill in the item structure with the appropriate details.
252 * 'leafname' field is set to NULL; text_width is unset.
254 void diritem_stat(guchar
*path
, DirItem
*item
, gboolean make_thumb
)
256 item
->leafname
= NULL
;
257 item
->may_delete
= FALSE
;
260 diritem_restat(path
, item
, make_thumb
);
263 /* Frees all fields in the icon, but does not free the icon structure
264 * itself (because it might be part of a larger structure).
266 void diritem_clear(DirItem
*item
)
268 g_return_if_fail(item
!= NULL
);
270 pixmap_unref(item
->image
);
271 g_free(item
->leafname
);
274 static void set_ignore_exec(guchar
*new)
276 o_ignore_exec
= atoi(new);