1 /*
2 OWFS -- One-Wire filesystem
3 OWHTTPD -- One-Wire Web Server
4 Written 2003 Paul H Alfille
5 email: paul.alfille@gmail.com
6 Released under the GPL
7 See the header file: ow.h for full attribution
8 1wire/iButton system from Dallas Semiconductor
9 */
10
11 #include <config.h>
12 #include "owfs_config.h"
13 #include "ow.h"
14 #include "ow_connection.h"
15
FS_fstat(const char * path,struct stat * stbuf)16 ZERO_OR_ERROR FS_fstat(const char *path, struct stat *stbuf)
17 {
18 struct parsedname pn;
19 ZERO_OR_ERROR ret = 0;
20
21 LEVEL_CALL("path=%s", SAFESTRING(path));
22
23 /* Bad path */
24 if (FS_ParsedName(path, &pn) != 0 ) {
25 return -ENOENT;
26 }
27
28 ret = FS_fstat_postparse(stbuf, &pn);
29 FS_ParsedName_destroy(&pn);
30 return ret;
31 }
32
33 /* Fstat with parsedname already done */
FS_fstat_postparse(struct stat * stbuf,const struct parsedname * pn)34 ZERO_OR_ERROR FS_fstat_postparse(struct stat *stbuf, const struct parsedname *pn)
35 {
36 memset(stbuf, 0, sizeof(struct stat));
37
38 LEVEL_CALL("ATTRIBUTES path=%s", SAFESTRING(pn->path));
39 if (KnownBus(pn) && pn->known_bus == NULL) {
40 /* check for presence of first in-device at least since FS_ParsedName
41 * doesn't do it yet. */
42 return -ENOENT;
43 } else if (pn->selected_device == NO_DEVICE) { /* root directory */
44 int nr = 0;
45 //printf("FS_fstat root\n");
46 stbuf->st_mode = S_IFDIR | 0755;
47 stbuf->st_nlink = 2; // plus number of sub-directories
48 nr = -1; // make it 1
49 /*
50 If calculating NSUB is hard, the filesystem can set st_nlink of
51 directories to 1, and find will still work. This is not documented
52 behavior of find, and it's not clear whether this is intended or just
53 by accident. But for example the NTFS filesysem relies on this, so
54 it's unlikely that this "feature" will go away.
55 */
56 stbuf->st_nlink += nr;
57 FSTATLOCK;
58 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.start_time;
59 FSTATUNLOCK;
60 stbuf->st_size = 4096 ; // Common directory size
61 return 0;
62 } else if (pn->selected_filetype == NO_FILETYPE) {
63 int nr = 0;
64 //printf("FS_fstat pn.selected_filetype == NULL (1-wire device)\n");
65 stbuf->st_mode = S_IFDIR | 0777;
66 stbuf->st_nlink = 2; // plus number of sub-directories
67
68 nr = -1; // make it 1
69 //printf("FS_fstat seem to be %d entries (%d dirs) in device\n", pn.selected_device->nft, nr);
70 stbuf->st_nlink += nr;
71 FSTATLOCK;
72 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
73 FSTATUNLOCK;
74 stbuf->st_size = 4096 ; // Common directory size
75 return 0;
76 } else if (pn->selected_filetype->format == ft_directory || pn->selected_filetype->format == ft_subdir) { /* other directory */
77 int nr = 0;
78 stbuf->st_mode = S_IFDIR | 0777;
79 stbuf->st_nlink = 2; // plus number of sub-directories
80 nr = -1; // make it 1
81 stbuf->st_nlink += nr;
82
83 FSTATLOCK;
84 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
85 FSTATUNLOCK;
86 stbuf->st_size = 4096 ; // Common directory size
87 return 0;
88 } else { /* known 1-wire filetype */
89 stbuf->st_mode = S_IFREG;
90 if (pn->selected_filetype->read != NO_READ_FUNCTION) {
91 stbuf->st_mode |= 0444;
92 }
93 if (!Globals.readonly && (pn->selected_filetype->write != NO_WRITE_FUNCTION)) {
94 stbuf->st_mode |= 0222;
95 }
96 stbuf->st_nlink = 1;
97
98 switch (pn->selected_filetype->change) {
99 case fc_volatile:
100 case fc_second:
101 case fc_statistic:
102 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = NOW_TIME;
103 break;
104 case fc_stable:
105 FSTATLOCK;
106 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
107 FSTATUNLOCK;
108 break;
109 default:
110 stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.start_time;
111 break;
112 }
113 stbuf->st_size = FullFileLength(pn);
114 return 0;
115 }
116 }
117