Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <stdio.h>
21 : : #include <ctype.h>
22 : : #include <stdlib.h>
23 : : #include <unistd.h>
24 : : #include <utime.h>
25 : :
26 : : #if defined LINUX || defined ANDROID
27 : : #include <mntent.h>
28 : : #define mnttab mntent
29 : : #elif defined AIX
30 : : #include <sys/mntctl.h>
31 : : #include <sys/vmount.h>
32 : : extern "C" int mntctl( int cmd, size_t size, char* buf );
33 : : #elif defined(NETBSD)
34 : : #include <sys/mount.h>
35 : : #elif defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
36 : : defined(DRAGONFLY) || defined(IOS)
37 : : struct mnttab
38 : : {
39 : : char *mnt_dir;
40 : : char *mnt_fsname;
41 : : };
42 : : #else
43 : : #include <sys/mnttab.h>
44 : : #endif
45 : :
46 : : #ifndef MAXPATHLEN
47 : : #define MAXPATHLEN 1024
48 : : #endif
49 : :
50 : : #include <tools/debug.hxx>
51 : : #include <tools/fsys.hxx>
52 : : #include "comdep.hxx"
53 : : #include <rtl/instance.hxx>
54 : :
55 : : #if defined SOLARIS
56 : : #define MOUNTSPECIAL mnt_special
57 : : #define MOUNTPOINT mnt_mountp
58 : : #define MOUNTOPTS mnt_mntopts
59 : : #define MOUNTFS mnt_fstype
60 : : #else
61 : : #define MOUNTSPECIAL mnt_fsname
62 : : #define MOUNTPOINT mnt_dir
63 : : #define MOUNTFS mnt_type
64 : : #endif
65 : :
66 : 0 : struct mymnttab
67 : : {
68 : : dev_t mountdevice;
69 : : rtl::OString mountspecial;
70 : : rtl::OString mountpoint;
71 : : rtl::OString mymnttab_filesystem;
72 : 0 : mymnttab() { mountdevice = (dev_t) -1; }
73 : : };
74 : :
75 : : #if defined(NETBSD) || defined(FREEBSD) || defined(MACOSX) || \
76 : : defined(OPENBSD) || defined(DRAGONFLY) || defined(IOS)
77 : : sal_Bool GetMountEntry(dev_t /* dev */, struct mymnttab * /* mytab */ )
78 : : {
79 : : DBG_WARNING( "Sorry, not implemented: GetMountEntry" );
80 : : return sal_False;
81 : : }
82 : : #elif defined AIX
83 : : sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab)
84 : : {
85 : : int bufsize;
86 : : if (mntctl (MCTL_QUERY, sizeof bufsize, (char*) &bufsize))
87 : : return sal_False;
88 : :
89 : : char* buffer = (char *)malloc( bufsize * sizeof(char) );
90 : : if (mntctl (MCTL_QUERY, bufsize, buffer) != -1)
91 : : for ( char* vmt = buffer;
92 : : vmt < buffer + bufsize;
93 : : vmt += ((struct vmount*)vmt)->vmt_length)
94 : : {
95 : : struct stat buf;
96 : : char *mountp = vmt2dataptr((struct vmount*)vmt, VMT_STUB);
97 : : if ((stat (mountp, &buf) != -1) && (buf.st_dev == dev))
98 : : {
99 : : mytab->mountpoint = mountp;
100 : : mytab->mountspecial
101 : : = vmt2dataptr((struct vmount*)vmt, VMT_HOSTNAME);
102 : : if (mytab->mountspecial.Len())
103 : : mytab->mountspecial += ':';
104 : : mytab->mountspecial
105 : : += vmt2dataptr((struct vmount*)vmt, VMT_OBJECT);
106 : : mytab->mountdevice = dev;
107 : : free( buffer );
108 : : return sal_True;
109 : : }
110 : : }
111 : : free( buffer );
112 : : return sal_False;
113 : : }
114 : : #else
115 : 0 : static sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab)
116 : : {
117 : : #if defined SOLARIS
118 : : FILE *fp = fopen (MNTTAB, "r");
119 : : if (! fp)
120 : : return sal_False;
121 : : struct mnttab mnt[1];
122 : : while (getmntent (fp, mnt) != -1)
123 : : #elif defined AIX || defined ANDROID
124 : : FILE *fp = NULL;
125 : : if (! fp)
126 : : return sal_False;
127 : : struct mnttab mnt[1];
128 : : while ( 0 )
129 : : #else
130 : 0 : FILE *fp = setmntent (MOUNTED, "r");
131 [ # # ]: 0 : if (! fp)
132 : 0 : return sal_False;
133 : : struct mnttab *mnt;
134 [ # # ]: 0 : while ((mnt = getmntent (fp)) != NULL)
135 : : #endif
136 : : {
137 : : #ifdef SOLARIS
138 : : char *devopt = NULL;
139 : : if ( mnt->MOUNTOPTS != NULL )
140 : : devopt = strstr (mnt->MOUNTOPTS, "dev=");
141 : : if (devopt)
142 : : {
143 : : if (dev != (dev_t) strtoul (devopt+4, NULL, 16))
144 : : continue;
145 : : }
146 : : else
147 : : #endif
148 : : {
149 : : struct stat buf;
150 [ # # ][ # # ]: 0 : if ((stat (mnt->MOUNTPOINT, &buf) == -1) || (buf.st_dev != dev))
[ # # ]
151 : 0 : continue;
152 : : }
153 : : # ifdef LINUX
154 : : // #61624# Opening file with setmntent and closing with fclose fails for glibc-2.1
155 : 0 : endmntent( fp );
156 : : # else
157 : : fclose (fp);
158 : : # endif
159 : 0 : mytab->mountspecial = mnt->MOUNTSPECIAL;
160 : 0 : mytab->mountpoint = mnt->MOUNTPOINT;
161 : 0 : mytab->mountdevice = dev;
162 : 0 : mytab->mymnttab_filesystem = mnt->MOUNTFS;
163 : :
164 : 0 : return sal_True;
165 : : }
166 : : # ifdef LINUX
167 : : /* #61624# see above */
168 : 0 : endmntent( fp );
169 : : # else
170 : : fclose (fp);
171 : : # endif
172 : 0 : return sal_False;
173 : : }
174 : : #endif
175 : :
176 : 26008 : sal_Bool DirEntry::ToAbs()
177 : : {
178 [ - + ]: 26008 : if ( FSYS_FLAG_VOLUME == eFlag )
179 : : {
180 : 0 : eFlag = FSYS_FLAG_ABSROOT;
181 : 0 : return sal_True;
182 : : }
183 : :
184 [ + - ][ + - ]: 26008 : if ( IsAbs() )
185 : 26008 : return sal_True;
186 : :
187 : : char sBuf[MAXPATHLEN + 1];
188 [ # # ][ # # ]: 0 : *this = DirEntry( String( getcwd( sBuf, MAXPATHLEN ), osl_getThreadTextEncoding() ) ) + *this;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
189 [ # # ]: 26008 : return IsAbs();
190 : : }
191 : :
192 : : namespace { struct mymnt : public rtl::Static< mymnttab, mymnt > {}; }
193 : :
194 : 0 : String DirEntry::GetVolume() const
195 : : {
196 : : DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
197 : :
198 [ # # ]: 0 : DirEntry aPath( *this );
199 [ # # ]: 0 : aPath.ToAbs();
200 : :
201 : : struct stat buf;
202 [ # # ][ # # ]: 0 : while (stat(rtl::OUStringToOString(aPath.GetFull(), osl_getThreadTextEncoding()).getStr(), &buf))
[ # # ][ # # ]
[ # # ][ # # ]
203 : : {
204 [ # # ][ # # ]: 0 : if (aPath.Level() <= 1)
205 [ # # ]: 0 : return String();
206 [ # # ][ # # ]: 0 : aPath = aPath [1];
207 : : }
208 : 0 : mymnttab &rMnt = mymnt::get();
209 [ # # ]: 0 : return ((buf.st_dev == rMnt.mountdevice || GetMountEntry(buf.st_dev, &rMnt)) ?
210 [ # # ]: 0 : rtl::OStringToOUString(rMnt.mountspecial, osl_getThreadTextEncoding()) :
211 [ # # ][ # # ]: 0 : rtl::OUString());
[ # # ][ # # ]
[ # # ]
212 : : }
213 : :
214 : 0 : sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const
215 : : {
216 : : DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
217 : :
218 [ # # ][ # # ]: 0 : rtl::OString aPath(rtl::OUStringToOString(GetFull(), osl_getThreadTextEncoding()));
[ # # ][ # # ]
[ # # ]
219 [ # # ]: 0 : if (!chdir(aPath.getStr()))
220 : : {
221 : 0 : return sal_True;
222 : : }
223 : : else
224 : : {
225 [ # # ][ # # ]: 0 : if (bSloppy && !chdir(aPath.getStr()))
[ # # ]
226 : : {
227 : 0 : return sal_True;
228 : : }
229 : : else
230 : : {
231 : 0 : return sal_False;
232 : : }
233 : 0 : }
234 : : }
235 : :
236 : 0 : sal_uInt16 DirReader_Impl::Init()
237 : : {
238 : 0 : return 0;
239 : : }
240 : :
241 : 0 : sal_uInt16 DirReader_Impl::Read()
242 : : {
243 [ # # ]: 0 : if (!pDosDir)
244 : : {
245 [ # # ][ # # ]: 0 : pDosDir = opendir(rtl::OUStringToOString(aPath, osl_getThreadTextEncoding()).getStr());
246 : : }
247 : :
248 [ # # ]: 0 : if (!pDosDir)
249 : : {
250 : 0 : bReady = sal_True;
251 : 0 : return 0;
252 : : }
253 : :
254 : : // List directories and dirs
255 [ # # ]: 0 : if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) &&
[ # # # # ]
[ # # ]
256 : 0 : ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
257 : : {
258 [ # # ][ # # ]: 0 : String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding());
259 [ # # ][ # # ]: 0 : if ( pDir->aNameMask.Matches( aD_Name ) )
260 : : {
261 : : DirEntryFlag eFlag =
262 : 0 : 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
263 : 0 : : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
264 [ # # ][ # # ]: 0 : : FSYS_FLAG_NORMAL;
265 [ # # ][ # # ]: 0 : DirEntry *pTemp = new DirEntry(rtl::OString(pDosEntry->d_name), eFlag);
266 [ # # ]: 0 : if ( pParent )
267 [ # # ][ # # ]: 0 : pTemp->ImpChangeParent( new DirEntry( *pParent ), sal_False);
[ # # ]
268 [ # # ]: 0 : FileStat aStat( *pTemp );
269 [ # # ][ # # ]: 0 : if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
[ # # ][ # # ]
[ # # ][ # # ]
270 [ # # ]: 0 : ( aStat.IsKind( FSYS_KIND_DIR ) ) ) ||
271 : : ( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
272 [ # # ]: 0 : !( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) &&
273 : : !( pDir->eAttrMask & FSYS_KIND_VISIBLE &&
274 [ # # ]: 0 : pDosEntry->d_name[0] == '.' ) )
275 : : {
276 [ # # ]: 0 : if ( pDir->pStatLst ) // Does sorting criteria require status?
277 [ # # ][ # # ]: 0 : pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) );
[ # # ]
278 : : else
279 [ # # ]: 0 : pDir->ImpSortedInsert( pTemp, NULL );
280 : 0 : return 1;
281 : : }
282 : : else
283 [ # # ][ # # ]: 0 : delete pTemp;
[ # # ][ # # ]
284 [ # # ][ # # ]: 0 : }
285 : : }
286 : : else
287 : 0 : bReady = sal_True;
288 : 0 : return 0;
289 : : }
290 : :
291 : 25966 : sal_Bool FileStat::Update( const DirEntry& rDirEntry, SAL_UNUSED_PARAMETER sal_Bool )
292 : : {
293 : :
294 : 25966 : nSize = 0;
295 : 25966 : nKindFlags = 0;
296 [ + - ]: 25966 : aCreator.Erase();
297 [ + - ]: 25966 : aType.Erase();
298 : 25966 : aDateCreated = Date(0);
299 [ + - ]: 25966 : aTimeCreated = Time(0);
300 : 25966 : aDateModified = Date(0);
301 [ + - ]: 25966 : aTimeModified = Time(0);
302 : 25966 : aDateAccessed = Date(0);
303 [ + - ]: 25966 : aTimeAccessed = Time(0);
304 : :
305 [ + - ][ - + ]: 25966 : if ( !rDirEntry.IsValid() )
306 : : {
307 : 0 : nError = FSYS_ERR_NOTEXISTS;
308 : 0 : return sal_False;
309 : : }
310 : :
311 : : // Special case if DirEntry is root
312 [ - + ]: 25966 : if ( rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
313 : : {
314 : 0 : nKindFlags = FSYS_KIND_DIR;
315 : 0 : nError = FSYS_ERR_OK;
316 : 0 : return sal_True;
317 : : }
318 : :
319 : : struct stat aStat;
320 [ + - ][ + - ]: 25966 : rtl::OString aPath(rtl::OUStringToOString(rDirEntry.GetFull(), osl_getThreadTextEncoding()));
[ + - ][ + - ]
[ + - ]
321 [ + + ]: 25966 : if (stat(aPath.getStr(), &aStat))
322 : : {
323 : : // pl: #67851#
324 : : // do this here, because an existing filename containing "wildcards"
325 : : // should be handled as a file, not a wildcard
326 : : // note that this is not a solution, since filenames containing special characters
327 : : // are handled badly across the whole Office
328 : :
329 : : // special treatment if name contains wildcards
330 [ + - ][ + - ]: 16636 : rtl::OString aTempName(rtl::OUStringToOString(rDirEntry.GetName(), osl_getThreadTextEncoding()));
[ + - ][ + - ]
[ + - ]
331 [ + - + - : 49908 : if ( aTempName.indexOf('?') != -1 ||
- + ][ - + ]
332 : 16636 : aTempName.indexOf('*') != -1 ||
333 : 16636 : aTempName.indexOf(';') != -1 )
334 : : {
335 : 0 : nKindFlags = FSYS_KIND_WILD;
336 : 0 : nError = FSYS_ERR_OK;
337 : 0 : return sal_True;
338 : : }
339 : :
340 : 16636 : nError = FSYS_ERR_NOTEXISTS;
341 : 16636 : return sal_False;
342 : : }
343 : :
344 : 9330 : nError = FSYS_ERR_OK;
345 : 9330 : nSize = aStat.st_size;
346 : :
347 : 9330 : nKindFlags = FSYS_KIND_UNKNOWN;
348 [ - + ]: 9330 : if ( ( aStat.st_mode & S_IFDIR ) == S_IFDIR )
349 : 0 : nKindFlags = nKindFlags | FSYS_KIND_DIR;
350 [ + - ]: 9330 : if ( ( aStat.st_mode & S_IFREG ) == S_IFREG )
351 : 9330 : nKindFlags = nKindFlags | FSYS_KIND_FILE;
352 [ - + ]: 9330 : if ( ( aStat.st_mode & S_IFCHR ) == S_IFCHR )
353 : 0 : nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_CHAR;
354 [ - + ]: 9330 : if ( ( aStat.st_mode & S_IFBLK ) == S_IFBLK )
355 : 0 : nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_BLOCK;
356 [ - + ]: 9330 : if ( nKindFlags == FSYS_KIND_UNKNOWN )
357 : 0 : nKindFlags = nKindFlags | FSYS_KIND_FILE;
358 : :
359 [ + - ]: 9330 : Unx2DateAndTime( aStat.st_ctime, aTimeCreated, aDateCreated );
360 [ + - ]: 9330 : Unx2DateAndTime( aStat.st_mtime, aTimeModified, aDateModified );
361 [ + - ]: 9330 : Unx2DateAndTime( aStat.st_atime, aTimeAccessed, aDateAccessed );
362 : :
363 : 25966 : return sal_True;
364 : : }
365 : :
366 : 0 : const char *TempDirImpl( char *pBuf )
367 : : {
368 : : #ifdef MACOSX
369 : : // P_tmpdir is /var/tmp on Mac OS X, and it is not cleaned up on system
370 : : // startup
371 : : strcpy( pBuf, "/tmp" );
372 : : #else
373 : 0 : const char *pValue = getenv( "TEMP" );
374 [ # # ]: 0 : if ( !pValue )
375 : 0 : pValue = getenv( "TMP" );
376 [ # # ]: 0 : if ( pValue )
377 : 0 : strcpy( pBuf, pValue );
378 : : else
379 : : // P_tempdir exists in Solaris and Linux
380 : 0 : strcpy( pBuf, P_tmpdir );
381 : : // don't use "/tmp" as hard coded directory
382 : : //strcpy( pBuf, "/tmp" );
383 : : #endif /* MACOSX */
384 : :
385 : 0 : return pBuf;
386 : : }
387 : :
388 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|