1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: regcomplazy.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <osl/diagnose.h>
35 #include <osl/thread.h>
36 #include <osl/file.hxx>
37 #include <rtl/strbuf.hxx>
38 #include <rtl/ustrbuf.hxx>
42 #include <registry/registry.hxx>
45 #define OUSTR(x) ::rtl::OUString::createFromAscii( x )
46 #define OSToOUS(x) ::rtl::OStringToOUString(x, osl_getThreadTextEncoding())
47 #define OUSToOS(x) ::rtl::OUStringToOString(x, osl_getThreadTextEncoding())
48 using namespace ::rtl
;
50 typedef ::std::vector
< ::rtl::OString
> OSVector
;
52 typedef ::std::pair
< ::rtl::OString
, OSVector
> DataPair
;
54 typedef ::std::vector
< DataPair
> DataVector
;
56 struct CompDescriptor
{
57 OString sImplementationName
;
58 OString sComponentName
;
60 OSVector vSupportedServices
;
64 typedef ::std::vector
< CompDescriptor
> CDescrVector
;
66 static void print_options() SAL_THROW( () )
69 "\nusage: regcomplazy [-v]registry_file cmp_descr_file ...\n\n"
70 "Register a cmponent using a comp description file.\n"
71 "Option -v prints verbose output on stdout.\n" );
74 static bool checkImplValue(RegistryValueList
<sal_Char
*>* pValueList
, OString sImplName
) {
75 for (sal_uInt32 i
=0; i
< pValueList
->getLength(); i
++) {
76 if (sImplName
.equals(pValueList
->getElement(i
)))
83 //==================================================================================================
84 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc
, argv
)
92 bool bVerbose
= false;
94 if ('-' == argv
[ nPos
][ 0 ] && 'v' == argv
[ nPos
][ 1 ])
96 if ('\0' != argv
[ nPos
][ 2 ])
105 OUString
sys_path( OUSTR( argv
[ nPos
] ) );
107 oslFileError rc
= osl_getFileURLFromSystemPath( sys_path
.pData
, ®_url
.pData
);
108 if (osl_File_E_None
!= rc
)
111 fprintf( stderr
, "\nERROR: cannot make file url out of %s\n", argv
[nPos
]);
115 FILE* fDescr
= fopen(argv
[ ++nPos
], "r");
116 OStringBuffer
sBuffer(512);
119 size_t totalSize
= 0;
123 while ( !feof(fDescr
) )
125 if ( (readSize
= fread(pBuffer
, 1, 512, fDescr
)) > 0
126 && !ferror(fDescr
) ) {
127 totalSize
+= readSize
;
128 if (totalSize
>= 512)
129 sBuffer
.ensureCapacity(totalSize
* 2);
131 sBuffer
.append(pBuffer
, readSize
);
135 fDescr
= 0; // just to be sure noone tries to use the file ever after
138 OString sDescr
= sBuffer
.makeStringAndClear();
139 sal_Int32 nTokenIndex
= 0;
142 CompDescriptor descr
;
146 OString sTmp
= sDescr
.getToken(0, '\x0A', nTokenIndex
);
147 OString
sToken(sTmp
);
148 if (sTmp
.pData
->buffer
[sTmp
.getLength()-1] == '\x0D')
149 sToken
= sTmp
.copy(0, sTmp
.getLength()-1);
151 if (sToken
.indexOf("[Data]") >= 0) {
153 OString sTmp2
= sDescr
.getToken(0, '\x0A', nTokenIndex
);
154 OString
sToken2(sTmp2
);
155 if (sTmp2
.pData
->buffer
[sTmp2
.getLength()-1] == '\x0D')
156 sToken2
= sTmp2
.copy(0, sTmp2
.getLength()-1);
158 if ((sToken2
.getLength() > 0) && (sToken2
.pData
->buffer
[0] != '[')) {
159 OString
dataKey(sToken2
.copy(0, sToken2
.indexOf('=')));
160 OString
sValues(sToken2
.copy(sToken2
.indexOf('=')+1));
161 sal_Int32 nVIndex
= 0;
164 OString sValue
= sValues
.getToken(0, ';', nVIndex
);
165 vValues
.push_back(sValue
);
166 } while (nVIndex
>= 0 );
167 descr
.vData
.push_back(DataPair(dataKey
, vValues
));
170 } while (nTokenIndex
>= 0 );
172 if ( sToken
.indexOf("[ComponentDescriptor]") >= 0) {
176 vDescr
.push_back(descr
);
178 descr
= CompDescriptor();
180 else if ( sToken
.indexOf("ImplementationName=") >= 0) {
181 descr
.sImplementationName
= sToken
.copy(19);
183 else if ( sToken
.indexOf("ComponentName=") >= 0) {
184 descr
.sComponentName
= sToken
.copy(14);
186 else if ( sToken
.indexOf("LoaderName=") >= 0) {
187 descr
.sLoaderName
= sToken
.copy(11);
189 else if ( (sToken
.indexOf("[SupportedServices]") < 0) &&
190 (sToken
.getLength() > 0) &&
191 (sToken
.pData
->buffer
[0] != '[') ) {
192 descr
.vSupportedServices
.push_back(sToken
);
194 } while (nTokenIndex
>= 0 );
195 // insert the last descriptor
196 vDescr
.push_back(descr
);
198 Registry
*pReg
= new Registry
;
200 RegistryKey rootKey
, key
, subKey
, serviceKey
;
202 if (pReg
->open(reg_url
, REG_READWRITE
))
204 if (pReg
->create(reg_url
))
207 fprintf(stderr
, "ERROR: open registry \"%s\" failed\n", argv
[1]);
211 if (pReg
->openRootKey(rootKey
)) {
213 fprintf(stderr
, "ERROR: open root key failed\n");
217 CDescrVector::const_iterator comp_iter
= vDescr
.begin();
219 OString sImplName
= (*comp_iter
).sImplementationName
;
220 OUStringBuffer sbImpl
;
221 sbImpl
.appendAscii("/IMPLEMENTATIONS/");
222 sbImpl
.append(OSToOUS(sImplName
));
223 OUString sImplKeyName
= sbImpl
.makeStringAndClear();
225 if (rootKey
.openKey(sImplKeyName
, key
) == REG_NO_ERROR
) {
227 fprintf(stderr
, "WARNING: implementation entry for \"%s\" already exists, existing entries are overwritten\n", sImplName
.getStr());
230 if (rootKey
.createKey(sImplKeyName
, key
)) {
232 fprintf(stderr
, "ERROR: can't create new implementation entry \"%s\".\n", sImplName
.getStr());
238 OString sLoaderName
= (*comp_iter
).sLoaderName
;
239 OUString
usKeyName(OUSTR("UNO/ACTIVATOR"));
240 key
.createKey(usKeyName
, subKey
);
241 subKey
.setValue(OUString(), RG_VALUETYPE_STRING
,
242 (sal_Char
*)sLoaderName
.getStr(), sLoaderName
.getLength()+1);
244 OString sCompName
= (*comp_iter
).sComponentName
;
245 usKeyName
= OUSTR("UNO/LOCATION");
246 key
.createKey(usKeyName
, subKey
);
247 subKey
.setValue(OUString(), RG_VALUETYPE_STRING
,
248 (sal_Char
*)sCompName
.getStr(), sCompName
.getLength()+1);
250 if ((*comp_iter
).vData
.size() > 0) {
251 usKeyName
= OUSTR("DATA");
252 RegistryKey dataKey
, valueKey
;
253 key
.createKey(usKeyName
, dataKey
);
255 DataVector::const_iterator data_iter
= ((*comp_iter
).vData
).begin();
257 OUString
sDataKey(OSToOUS((*data_iter
).first
));
258 dataKey
.createKey(sDataKey
, valueKey
);
260 OSVector::const_iterator value_iter
= ((*data_iter
).second
).begin();
261 int vlen
= (*data_iter
).second
.size();
262 sal_Char
** pValueList
= (sal_Char
**)rtl_allocateZeroMemory(
263 vlen
* sizeof(sal_Char
*));
266 pValueList
[i
] = (sal_Char
*)rtl_allocateZeroMemory(
267 (*value_iter
).getLength()+1 * sizeof(sal_Char
));
268 rtl_copyMemory(pValueList
[i
], (sal_Char
*)(*value_iter
).getStr(),
269 (*value_iter
).getLength()+1);
272 } while (value_iter
!= (*data_iter
).second
.end());
274 valueKey
.setStringListValue(OUString(), pValueList
, vlen
);
277 for (i
=0; i
<vlen
; i
++)
278 rtl_freeMemory(pValueList
[i
]);
279 rtl_freeMemory(pValueList
);
282 } while (data_iter
!= (*comp_iter
).vData
.end());
285 usKeyName
= OUSTR("UNO/SERVICES");
286 key
.createKey(usKeyName
, subKey
);
288 rootKey
.createKey(OUSTR("/SERVICES"), serviceKey
);
290 OSVector::const_iterator serv_iter
= ((*comp_iter
).vSupportedServices
).begin();
291 OUString usServiceKeyName
;
293 usServiceKeyName
= OSToOUS(*serv_iter
);
294 // write service key in impl section
295 subKey
.createKey(usServiceKeyName
, key
);
297 if (serviceKey
.openKey(usServiceKeyName
, key
) == REG_NO_ERROR
) {
298 RegistryValueList
<sal_Char
*> valueList
;
299 serviceKey
.getStringListValue(usServiceKeyName
, valueList
);
300 if ( checkImplValue(&valueList
, sImplName
) ) {
305 sal_uInt32 nServices
= valueList
.getLength()+1;
306 sal_Char
** pImplList
= (sal_Char
**)rtl_allocateZeroMemory(
307 nServices
* sizeof(sal_Char
*));
308 pImplList
[0] = (sal_Char
*)rtl_allocateZeroMemory(
309 sImplName
.getLength()+1 * sizeof(sal_Char
));
310 rtl_copyMemory(pImplList
[0], (sal_Char
*)sImplName
.getStr(),
311 sImplName
.getLength()+1);
312 for (sal_uInt32 i
=0; i
< valueList
.getLength(); i
++) {
313 pImplList
[i
+1]=valueList
.getElement(i
);
315 key
.setStringListValue(OUString(), pImplList
, nServices
);
318 rtl_freeMemory(pImplList
[0]);
319 rtl_freeMemory(pImplList
);
322 serviceKey
.createKey(usServiceKeyName
, key
);
324 sal_Char
* pImplList
[1];
325 pImplList
[0] = (sal_Char
*)rtl_allocateZeroMemory(
326 sImplName
.getLength()+1 * sizeof(sal_Char
));
327 rtl_copyMemory(pImplList
[0], (sal_Char
*)sImplName
.getStr(),
328 sImplName
.getLength()+1);
329 key
.setStringListValue(OUString(), pImplList
, 1);
332 rtl_freeMemory(pImplList
[0]);
335 } while (serv_iter
!= (*comp_iter
).vSupportedServices
.end());
338 } while (comp_iter
!= vDescr
.end());
342 serviceKey
.closeKey();