VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • 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 98103 2023-01-17 14:15:46Z 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 rc = 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 rc = RTProcQueryUsernameA(RTProcSelf(), &pszUser);
57 if (RT_SUCCESS(rc))
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 rc = RTStrAPrintf(&pszFile, "%s/%s.%s",
71 m_pszAutostartDbPath, pszUser, fAutostart ? "start" : "stop");
72 if (RT_SUCCESS(rc))
73 {
74 rc = RTFileOpen(&hAutostartFile, pszFile, fOpen);
75 if (RT_SUCCESS(rc))
76 {
77 uint64_t cbFile;
78
79 /*
80 * Files with more than 16 bytes are rejected because they just contain
81 * a number of the amount of VMs with autostart configured, so they
82 * should be really really small. Anything else is bogus.
83 */
84 rc = RTFileQuerySize(hAutostartFile, &cbFile);
85 if ( RT_SUCCESS(rc)
86 && cbFile <= 16)
87 {
88 char abBuf[16 + 1]; /* trailing \0 */
89 uint32_t cAutostartVms = 0;
90
91 RT_ZERO(abBuf);
92
93 /* Check if the file was just created. */
94 if (cbFile)
95 {
96 rc = RTFileRead(hAutostartFile, abBuf, (size_t)cbFile, NULL);
97 if (RT_SUCCESS(rc))
98 {
99 rc = RTStrToUInt32Ex(abBuf, NULL, 10 /* uBase */, &cAutostartVms);
100 if ( rc == VWRN_TRAILING_CHARS
101 || rc == VWRN_TRAILING_SPACES)
102 rc = VINF_SUCCESS;
103 }
104 }
105
106 if (RT_SUCCESS(rc))
107 {
108 size_t cbBuf;
109
110 /* Modify VM counter and write back. */
111 if (fAddVM)
112 cAutostartVms++;
113 else
114 cAutostartVms--;
115
116 if (cAutostartVms > 0)
117 {
118 cbBuf = RTStrPrintf(abBuf, sizeof(abBuf), "%u", cAutostartVms);
119 rc = RTFileSetSize(hAutostartFile, cbBuf);
120 if (RT_SUCCESS(rc))
121 rc = RTFileWriteAt(hAutostartFile, 0, abBuf, cbBuf, NULL);
122 }
123 else
124 {
125 /* Just delete the file if there are no VMs left. */
126 RTFileClose(hAutostartFile);
127 RTFileDelete(pszFile);
128 hAutostartFile = NIL_RTFILE;
129 }
130 }
131 }
132 else if (RT_SUCCESS(rc))
133 rc = VERR_FILE_TOO_BIG;
134
135 if (hAutostartFile != NIL_RTFILE)
136 RTFileClose(hAutostartFile);
137 }
138 RTStrFree(pszFile);
139 }
140
141 RTStrFree(pszUser);
142 }
143
144 return rc;
145}
146
147#endif
148
149AutostartDb::AutostartDb()
150{
151#ifdef RT_OS_LINUX
152 int rc = RTCritSectInit(&this->CritSect);
153 NOREF(rc);
154 m_pszAutostartDbPath = NULL;
155#endif
156}
157
158AutostartDb::~AutostartDb()
159{
160#ifdef RT_OS_LINUX
161 RTCritSectDelete(&this->CritSect);
162 if (m_pszAutostartDbPath)
163 RTStrFree(m_pszAutostartDbPath);
164#endif
165}
166
167int AutostartDb::setAutostartDbPath(const char *pszAutostartDbPathNew)
168{
169#if defined(RT_OS_LINUX)
170 char *pszAutostartDbPathTmp = NULL;
171
172 if (pszAutostartDbPathNew)
173 {
174 pszAutostartDbPathTmp = RTStrDup(pszAutostartDbPathNew);
175 if (!pszAutostartDbPathTmp)
176 return VERR_NO_MEMORY;
177 }
178
179 RTCritSectEnter(&this->CritSect);
180 if (m_pszAutostartDbPath)
181 RTStrFree(m_pszAutostartDbPath);
182
183 m_pszAutostartDbPath = pszAutostartDbPathTmp;
184 RTCritSectLeave(&this->CritSect);
185 return VINF_SUCCESS;
186#else
187 NOREF(pszAutostartDbPathNew);
188 return VERR_NOT_SUPPORTED;
189#endif
190}
191
192int AutostartDb::addAutostartVM(const char *pszVMId)
193{
194 int rc = VERR_NOT_SUPPORTED;
195
196#if defined(RT_OS_LINUX)
197 NOREF(pszVMId); /* Not needed */
198
199 RTCritSectEnter(&this->CritSect);
200 rc = autostartModifyDb(true /* fAutostart */, true /* fAddVM */);
201 RTCritSectLeave(&this->CritSect);
202#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
203 NOREF(pszVMId); /* Not needed */
204 rc = VINF_SUCCESS;
205#else
206 NOREF(pszVMId);
207 rc = VERR_NOT_SUPPORTED;
208#endif
209
210 return rc;
211}
212
213int AutostartDb::removeAutostartVM(const char *pszVMId)
214{
215 int rc = VINF_SUCCESS;
216
217#if defined(RT_OS_LINUX)
218 NOREF(pszVMId); /* Not needed */
219 RTCritSectEnter(&this->CritSect);
220 rc = autostartModifyDb(true /* fAutostart */, false /* fAddVM */);
221 RTCritSectLeave(&this->CritSect);
222#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
223 NOREF(pszVMId); /* Not needed */
224 rc = VINF_SUCCESS;
225#else
226 NOREF(pszVMId);
227 rc = VERR_NOT_SUPPORTED;
228#endif
229
230 return rc;
231}
232
233int AutostartDb::addAutostopVM(const char *pszVMId)
234{
235 int rc = VINF_SUCCESS;
236
237#if defined(RT_OS_LINUX)
238 NOREF(pszVMId); /* Not needed */
239 RTCritSectEnter(&this->CritSect);
240 rc = autostartModifyDb(false /* fAutostart */, true /* fAddVM */);
241 RTCritSectLeave(&this->CritSect);
242#elif defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
243 NOREF(pszVMId); /* Not needed */
244 rc = VINF_SUCCESS;
245#else
246 NOREF(pszVMId);
247 rc = VERR_NOT_SUPPORTED;
248#endif
249
250 return rc;
251}
252
253int AutostartDb::removeAutostopVM(const char *pszVMId)
254{
255 int rc = VINF_SUCCESS;
256
257#if defined(RT_OS_LINUX)
258 NOREF(pszVMId); /* Not needed */
259 RTCritSectEnter(&this->CritSect);
260 rc = autostartModifyDb(false /* fAutostart */, false /* fAddVM */);
261 RTCritSectLeave(&this->CritSect);
262#elif defined(RT_OS_DARWIN) || defined (RT_OS_WINDOWS)
263 NOREF(pszVMId); /* Not needed */
264 rc = VINF_SUCCESS;
265#else
266 NOREF(pszVMId);
267 rc = VERR_NOT_SUPPORTED;
268#endif
269
270 return rc;
271}
272
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use