VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/generic/AutostartDb-generic.cpp

Last change on this file was 98288, checked in by vboxsync, 15 months ago

Main/src-server: rc -> hrc/vrc (partial). bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: AutostartDb-generic.cpp 98288 2023-01-24 15:32:43Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Autostart implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include <VBox/err.h>
29#include <VBox/log.h>
30#include <iprt/assert.h>
31#include <iprt/process.h>
32#include <iprt/path.h>
33#include <iprt/mem.h>
34#include <iprt/file.h>
35#include <iprt/string.h>
36
37#include "AutostartDb.h"
38
39#if defined(RT_OS_LINUX)
40/**
41 * Modifies the autostart database.
42 *
43 * @returns VBox status code.
44 * @param fAutostart Flag whether the autostart or autostop database is modified.
45 * @param fAddVM Flag whether a VM is added or removed from the database.
46 */
47int AutostartDb::autostartModifyDb(bool fAutostart, bool fAddVM)
48{
49 int vrc = VINF_SUCCESS;
50 char *pszUser = NULL;
51
52 /* Check if the path is set. */
53 if (!m_pszAutostartDbPath)
54 return VERR_PATH_NOT_FOUND;
55
56 vrc = RTProcQueryUsernameA(RTProcSelf(), &pszUser);
57 if (RT_SUCCESS(vrc))
58 {
59 char *pszFile;
60 uint64_t fOpen = RTFILE_O_DENY_ALL | RTFILE_O_READWRITE;
61 RTFILE hAutostartFile;
62
63 AssertPtr(pszUser);
64
65 if (fAddVM)
66 fOpen |= RTFILE_O_OPEN_CREATE;
67 else
68 fOpen |= RTFILE_O_OPEN;
69
70 vrc = RTStrAPrintf(&pszFile, "%s/%s.%s", m_pszAutostartDbPath, pszUser, fAutostart ? "start" : "stop");
71 if (RT_SUCCESS(vrc))
72 {
73 vrc = RTFileOpen(&hAutostartFile, pszFile, fOpen);
74 if (RT_SUCCESS(vrc))
75 {
76 uint64_t cbFile;
77
78 /*
79 * Files with more than 16 bytes are rejected because they just contain
80 * a number of the amount of VMs with autostart configured, so they
81 * should be really really small. Anything else is bogus.
82 */
83 vrc = RTFileQuerySize(hAutostartFile, &cbFile);
84 if ( RT_SUCCESS(vrc)
85 && cbFile <= 16)
86 {
87 char abBuf[16 + 1]; /* trailing \0 */
88 uint32_t cAutostartVms = 0;
89
90 RT_ZERO(abBuf);
91
92 /* Check if the file was just created. */
93 if (cbFile)
94 {
95 vrc = RTFileRead(hAutostartFile, abBuf, (size_t)cbFile, NULL);
96 if (RT_SUCCESS(vrc))
97 {
98 vrc = RTStrToUInt32Ex(abBuf, NULL, 10 /* uBase */, &cAutostartVms);
99 if ( vrc == VWRN_TRAILING_CHARS
100 || vrc == VWRN_TRAILING_SPACES)
101 vrc = VINF_SUCCESS;
102 }
103 }
104
105 if (RT_SUCCESS(vrc))
106 {
107 size_t cbBuf;
108
109 /* Modify VM counter and write back. */
110 if (fAddVM)
111 cAutostartVms++;
112 else
113 cAutostartVms--;
114
115 if (cAutostartVms > 0)
116 {
117 cbBuf = RTStrPrintf(abBuf, sizeof(abBuf), "%u", cAutostartVms);
118 vrc = RTFileSetSize(hAutostartFile, cbBuf);
119 if (RT_SUCCESS(vrc))
120 vrc = RTFileWriteAt(hAutostartFile, 0, abBuf, cbBuf, NULL);
121 }
122 else
123 {
124 /* Just delete the file if there are no VMs left. */
125 RTFileClose(hAutostartFile);
126 RTFileDelete(pszFile);
127 hAutostartFile = NIL_RTFILE;
128 }
129 }
130 }
131 else if (RT_SUCCESS(vrc))
132 vrc = VERR_FILE_TOO_BIG;
133
134 if (hAutostartFile != NIL_RTFILE)
135 RTFileClose(hAutostartFile);
136 }
137 RTStrFree(pszFile);
138 }
139
140 RTStrFree(pszUser);
141 }
142
143 return vrc;
144}
145
146#endif
147
148AutostartDb::AutostartDb()
149{
150#ifdef RT_OS_LINUX
151 int vrc = RTCritSectInit(&this->CritSect);
152 NOREF(vrc);
153 m_pszAutostartDbPath = NULL;
154#endif
155}
156
157AutostartDb::~AutostartDb()
158{
159#ifdef RT_OS_LINUX
160 RTCritSectDelete(&this->CritSect);
161 if (m_pszAutostartDbPath)
162 RTStrFree(m_pszAutostartDbPath);
163#endif
164}
165
166int AutostartDb::setAutostartDbPath(const char *pszAutostartDbPathNew)
167{
168#if defined(RT_OS_LINUX)
169 char *pszAutostartDbPathTmp = NULL;
170
171 if (pszAutostartDbPathNew)
172 {
173 pszAutostartDbPathTmp = RTStrDup(pszAutostartDbPathNew);
174 if (!pszAutostartDbPathTmp)
175 return VERR_NO_MEMORY;
176 }
177
178 RTCritSectEnter(&this->CritSect);
179 if (m_pszAutostartDbPath)
180 RTStrFree(m_pszAutostartDbPath);
181
182 m_pszAutostartDbPath = pszAutostartDbPathTmp;
183 RTCritSectLeave(&this->CritSect);
184 return VINF_SUCCESS;
185#else
186 NOREF(pszAutostartDbPathNew);
187 return VERR_NOT_SUPPORTED;
188#endif
189}
190
191int AutostartDb::addAutostartVM(const char *pszVMId)
192{
193 int vrc = VERR_NOT_SUPPORTED;
194
195#if defined(RT_OS_LINUX)
196 NOREF(pszVMId); /* Not needed */
197
198 RTCritSectEnter(&this->CritSect);
199 vrc = autostartModifyDb(true /* fAutostart */, true /* fAddVM */);
200 RTCritSectLeave(&this->CritSect);
201#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
202 NOREF(pszVMId); /* Not needed */
203 vrc = VINF_SUCCESS;
204#else
205 NOREF(pszVMId);
206 vrc = VERR_NOT_SUPPORTED;
207#endif
208
209 return vrc;
210}
211
212int AutostartDb::removeAutostartVM(const char *pszVMId)
213{
214 int vrc = VINF_SUCCESS;
215
216#if defined(RT_OS_LINUX)
217 NOREF(pszVMId); /* Not needed */
218 RTCritSectEnter(&this->CritSect);
219 vrc = autostartModifyDb(true /* fAutostart */, false /* fAddVM */);
220 RTCritSectLeave(&this->CritSect);
221#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
222 NOREF(pszVMId); /* Not needed */
223 vrc = VINF_SUCCESS;
224#else
225 NOREF(pszVMId);
226 vrc = VERR_NOT_SUPPORTED;
227#endif
228
229 return vrc;
230}
231
232int AutostartDb::addAutostopVM(const char *pszVMId)
233{
234 int vrc = VINF_SUCCESS;
235
236#if defined(RT_OS_LINUX)
237 NOREF(pszVMId); /* Not needed */
238 RTCritSectEnter(&this->CritSect);
239 vrc = autostartModifyDb(false /* fAutostart */, true /* fAddVM */);
240 RTCritSectLeave(&this->CritSect);
241#elif defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
242 NOREF(pszVMId); /* Not needed */
243 vrc = VINF_SUCCESS;
244#else
245 NOREF(pszVMId);
246 vrc = VERR_NOT_SUPPORTED;
247#endif
248
249 return vrc;
250}
251
252int AutostartDb::removeAutostopVM(const char *pszVMId)
253{
254 int vrc = VINF_SUCCESS;
255
256#if defined(RT_OS_LINUX)
257 NOREF(pszVMId); /* Not needed */
258 RTCritSectEnter(&this->CritSect);
259 vrc = autostartModifyDb(false /* fAutostart */, false /* fAddVM */);
260 RTCritSectLeave(&this->CritSect);
261#elif defined(RT_OS_DARWIN) || defined (RT_OS_WINDOWS)
262 NOREF(pszVMId); /* Not needed */
263 vrc = VINF_SUCCESS;
264#else
265 NOREF(pszVMId);
266 vrc = VERR_NOT_SUPPORTED;
267#endif
268
269 return vrc;
270}
271
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use