Fix more class/struct mixups.
[haiku.git] / src / add-ons / kernel / file_systems / packagefs / volume / PackagesDirectory.cpp
blobbc4b61b34f43b1f574f7498ab8a0f93ff6511216
1 /*
2 * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "PackagesDirectory.h"
9 #include <errno.h>
11 #include <fs/KPath.h>
12 #include <team.h>
13 #include <vfs.h>
15 #include "DebugSupport.h"
18 PackagesDirectory::PackagesDirectory()
20 fStateName(),
21 fPath(NULL),
22 fDirFD(-1),
23 fNodeRef(),
24 fHashNext(NULL)
29 PackagesDirectory::~PackagesDirectory()
31 if (fDirFD >= 0)
32 close(fDirFD);
34 free(fPath);
38 /*static*/ bool
39 PackagesDirectory::IsNewer(const PackagesDirectory* a,
40 const PackagesDirectory* b)
42 if (b->fStateName.IsEmpty())
43 return false;
44 if (a->fStateName.IsEmpty())
45 return true;
46 return strcmp(a->fStateName, b->fStateName) > 0;
50 status_t
51 PackagesDirectory::Init(const char* path, dev_t mountPointDeviceID,
52 ino_t mountPointNodeID, struct stat& _st)
54 // Open the directory. We want the path be interpreted depending on from
55 // where it came (kernel or userland), but we always want a FD in the
56 // kernel I/O context. There's no VFS service method to do that for us,
57 // so we need to do that ourselves.
58 bool calledFromKernel
59 = team_get_current_team_id() == team_get_kernel_team_id();
60 // Not entirely correct, but good enough for now. The only
61 // alternative is to have that information passed in as well.
63 struct vnode* vnode;
64 status_t error;
65 if (path != NULL) {
66 error = vfs_get_vnode_from_path(path, calledFromKernel, &vnode);
67 } else {
68 // No path given -- use the "packages" directory at our mount point.
69 error = vfs_entry_ref_to_vnode(mountPointDeviceID, mountPointNodeID,
70 "packages", &vnode);
72 if (error != B_OK) {
73 ERROR("Failed to open packages directory \"%s\"\n", strerror(error));
74 RETURN_ERROR(error);
77 return _Init(vnode, _st);
81 status_t
82 PackagesDirectory::InitOldState(dev_t adminDirDeviceID, ino_t adminDirNodeID,
83 const char* stateName)
85 if (!fStateName.SetTo(stateName))
86 RETURN_ERROR(B_NO_MEMORY);
88 struct vnode* vnode;
89 status_t error = vfs_entry_ref_to_vnode(adminDirDeviceID, adminDirNodeID,
90 stateName, &vnode);
91 if (error != B_OK) {
92 ERROR("Failed to open old state directory \"%s\"\n", strerror(error));
93 RETURN_ERROR(error);
96 struct stat st;
97 return _Init(vnode, st);
101 status_t
102 PackagesDirectory::_Init(struct vnode* vnode, struct stat& _st)
104 fDirFD = vfs_open_vnode(vnode, O_RDONLY, true);
106 if (fDirFD < 0) {
107 ERROR("Failed to open packages directory \"%s\"\n", strerror(fDirFD));
108 vfs_put_vnode(vnode);
109 RETURN_ERROR(fDirFD);
111 // Our vnode reference has been transferred to the FD.
113 // Is it a directory at all?
114 struct stat& st = _st;
115 if (fstat(fDirFD, &st) < 0)
116 RETURN_ERROR(errno);
118 fNodeRef.device = st.st_dev;
119 fNodeRef.node = st.st_ino;
121 // get a normalized path
122 KPath normalizedPath;
123 if (normalizedPath.InitCheck() != B_OK)
124 RETURN_ERROR(normalizedPath.InitCheck());
126 char* normalizedPathBuffer = normalizedPath.LockBuffer();
127 status_t error = vfs_entry_ref_to_path(fNodeRef.device, fNodeRef.node, NULL,
128 true, normalizedPathBuffer, normalizedPath.BufferSize());
129 if (error != B_OK)
130 RETURN_ERROR(error);
132 fPath = strdup(normalizedPathBuffer);
133 if (fPath == NULL)
134 RETURN_ERROR(B_NO_MEMORY);
136 return B_OK;