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
RevLine 
[41999]1/* $Id: AutostartDb-generic.cpp 98288 2023-01-24 15:32:43Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Autostart implementation.
4 */
5
6/*
[98103]7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
[41999]8 *
[96407]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
[41999]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 */
[42181]47int AutostartDb::autostartModifyDb(bool fAutostart, bool fAddVM)
[41999]48{
[98288]49 int vrc = VINF_SUCCESS;
[41999]50 char *pszUser = NULL;
51
[42181]52 /* Check if the path is set. */
53 if (!m_pszAutostartDbPath)
54 return VERR_PATH_NOT_FOUND;
55
[98288]56 vrc = RTProcQueryUsernameA(RTProcSelf(), &pszUser);
57 if (RT_SUCCESS(vrc))
[41999]58 {
59 char *pszFile;
60 uint64_t fOpen = RTFILE_O_DENY_ALL | RTFILE_O_READWRITE;
61 RTFILE hAutostartFile;
62
[42069]63 AssertPtr(pszUser);
64
[41999]65 if (fAddVM)
66 fOpen |= RTFILE_O_OPEN_CREATE;
[42118]67 else
68 fOpen |= RTFILE_O_OPEN;
[41999]69
[98288]70 vrc = RTStrAPrintf(&pszFile, "%s/%s.%s", m_pszAutostartDbPath, pszUser, fAutostart ? "start" : "stop");
71 if (RT_SUCCESS(vrc))
[41999]72 {
[98288]73 vrc = RTFileOpen(&hAutostartFile, pszFile, fOpen);
74 if (RT_SUCCESS(vrc))
[41999]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 */
[98288]83 vrc = RTFileQuerySize(hAutostartFile, &cbFile);
84 if ( RT_SUCCESS(vrc)
[41999]85 && cbFile <= 16)
86 {
87 char abBuf[16 + 1]; /* trailing \0 */
88 uint32_t cAutostartVms = 0;
89
[47117]90 RT_ZERO(abBuf);
[41999]91
92 /* Check if the file was just created. */
93 if (cbFile)
94 {
[98288]95 vrc = RTFileRead(hAutostartFile, abBuf, (size_t)cbFile, NULL);
96 if (RT_SUCCESS(vrc))
[41999]97 {
[98288]98 vrc = RTStrToUInt32Ex(abBuf, NULL, 10 /* uBase */, &cAutostartVms);
99 if ( vrc == VWRN_TRAILING_CHARS
100 || vrc == VWRN_TRAILING_SPACES)
101 vrc = VINF_SUCCESS;
[41999]102 }
103 }
104
[98288]105 if (RT_SUCCESS(vrc))
[41999]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);
[98288]118 vrc = RTFileSetSize(hAutostartFile, cbBuf);
119 if (RT_SUCCESS(vrc))
120 vrc = RTFileWriteAt(hAutostartFile, 0, abBuf, cbBuf, NULL);
[41999]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 }
[98288]131 else if (RT_SUCCESS(vrc))
132 vrc = VERR_FILE_TOO_BIG;
[41999]133
134 if (hAutostartFile != NIL_RTFILE)
135 RTFileClose(hAutostartFile);
136 }
137 RTStrFree(pszFile);
138 }
[42069]139
140 RTStrFree(pszUser);
[41999]141 }
142
[98288]143 return vrc;
[41999]144}
145
146#endif
147
148AutostartDb::AutostartDb()
149{
150#ifdef RT_OS_LINUX
[98288]151 int vrc = RTCritSectInit(&this->CritSect);
152 NOREF(vrc);
[42181]153 m_pszAutostartDbPath = NULL;
[41999]154#endif
155}
156
157AutostartDb::~AutostartDb()
158{
159#ifdef RT_OS_LINUX
160 RTCritSectDelete(&this->CritSect);
[42181]161 if (m_pszAutostartDbPath)
162 RTStrFree(m_pszAutostartDbPath);
[41999]163#endif
164}
165
[42181]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);
[42182]187 return VERR_NOT_SUPPORTED;
[42181]188#endif
189}
190
[41999]191int AutostartDb::addAutostartVM(const char *pszVMId)
192{
[98288]193 int vrc = VERR_NOT_SUPPORTED;
[41999]194
195#if defined(RT_OS_LINUX)
196 NOREF(pszVMId); /* Not needed */
197
198 RTCritSectEnter(&this->CritSect);
[98288]199 vrc = autostartModifyDb(true /* fAutostart */, true /* fAddVM */);
[41999]200 RTCritSectLeave(&this->CritSect);
[80569]201#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
[41999]202 NOREF(pszVMId); /* Not needed */
[98288]203 vrc = VINF_SUCCESS;
[41999]204#else
205 NOREF(pszVMId);
[98288]206 vrc = VERR_NOT_SUPPORTED;
[41999]207#endif
208
[98288]209 return vrc;
[41999]210}
211
212int AutostartDb::removeAutostartVM(const char *pszVMId)
213{
[98288]214 int vrc = VINF_SUCCESS;
[41999]215
216#if defined(RT_OS_LINUX)
217 NOREF(pszVMId); /* Not needed */
218 RTCritSectEnter(&this->CritSect);
[98288]219 vrc = autostartModifyDb(true /* fAutostart */, false /* fAddVM */);
[41999]220 RTCritSectLeave(&this->CritSect);
[80569]221#elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
[41999]222 NOREF(pszVMId); /* Not needed */
[98288]223 vrc = VINF_SUCCESS;
[41999]224#else
225 NOREF(pszVMId);
[98288]226 vrc = VERR_NOT_SUPPORTED;
[41999]227#endif
228
[98288]229 return vrc;
[41999]230}
231
232int AutostartDb::addAutostopVM(const char *pszVMId)
233{
[98288]234 int vrc = VINF_SUCCESS;
[41999]235
236#if defined(RT_OS_LINUX)
237 NOREF(pszVMId); /* Not needed */
238 RTCritSectEnter(&this->CritSect);
[98288]239 vrc = autostartModifyDb(false /* fAutostart */, true /* fAddVM */);
[41999]240 RTCritSectLeave(&this->CritSect);
[80569]241#elif defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
[41999]242 NOREF(pszVMId); /* Not needed */
[98288]243 vrc = VINF_SUCCESS;
[41999]244#else
245 NOREF(pszVMId);
[98288]246 vrc = VERR_NOT_SUPPORTED;
[41999]247#endif
248
[98288]249 return vrc;
[41999]250}
251
252int AutostartDb::removeAutostopVM(const char *pszVMId)
253{
[98288]254 int vrc = VINF_SUCCESS;
[41999]255
256#if defined(RT_OS_LINUX)
257 NOREF(pszVMId); /* Not needed */
258 RTCritSectEnter(&this->CritSect);
[98288]259 vrc = autostartModifyDb(false /* fAutostart */, false /* fAddVM */);
[41999]260 RTCritSectLeave(&this->CritSect);
[80569]261#elif defined(RT_OS_DARWIN) || defined (RT_OS_WINDOWS)
[41999]262 NOREF(pszVMId); /* Not needed */
[98288]263 vrc = VINF_SUCCESS;
[41999]264#else
265 NOREF(pszVMId);
[98288]266 vrc = VERR_NOT_SUPPORTED;
[41999]267#endif
268
[98288]269 return vrc;
[41999]270}
271
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use