VirtualBox

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

Last change on this file since 78242 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette