Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 4834:b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 12 Jan 2010 01:38:04 -0600 |
parents | 780bb5441c14 |
children | a03421eb562b |
comparison
equal
deleted
inserted
replaced
4833:4dd2389173fc | 4834:b3ea9c582280 |
---|---|
1 /* File IO for XEmacs. | 1 /* File IO for XEmacs. |
2 Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc. | 2 Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc. |
3 Copyright (C) 1996, 2001, 2002, 2003, 2004 Ben Wing. | 3 Copyright (C) 1996, 2001, 2002, 2003, 2004, 2010 Ben Wing. |
4 | 4 |
5 This file is part of XEmacs. | 5 This file is part of XEmacs. |
6 | 6 |
7 XEmacs is free software; you can redistribute it and/or modify it | 7 XEmacs is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | 8 under the terms of the GNU General Public License as published by the |
1386 #if defined (WIN32_FILENAMES) && defined (CYGWIN) | 1386 #if defined (WIN32_FILENAMES) && defined (CYGWIN) |
1387 /* When using win32 filenames in cygwin we want file-truename to | 1387 /* When using win32 filenames in cygwin we want file-truename to |
1388 detect that c:/windows == /windows for example. */ | 1388 detect that c:/windows == /windows for example. */ |
1389 if (! (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1]))) | 1389 if (! (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1]))) |
1390 { | 1390 { |
1391 LOCAL_TO_WIN32_FILE_FORMAT (path, p); | 1391 LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN (path, p); |
1392 path = p; | 1392 path = p; |
1393 } | 1393 } |
1394 #endif | 1394 #endif |
1395 p = path; | 1395 p = path; |
1396 | 1396 |
2269 | 2269 |
2270 /* netunam, being a strange-o system call only used once, is not | 2270 /* netunam, being a strange-o system call only used once, is not |
2271 encapsulated. */ | 2271 encapsulated. */ |
2272 | 2272 |
2273 LISP_STRING_TO_EXTERNAL (path, path_ext, Qfile_name); | 2273 LISP_STRING_TO_EXTERNAL (path, path_ext, Qfile_name); |
2274 LISP_STRING_TO_EXTERNAL (login, login_ext, Qnative); | 2274 LISP_STRING_TO_EXTERNAL (login, login_ext, Quser_name_encoding); |
2275 | 2275 |
2276 netresult = netunam (path_ext, login_ext); | 2276 netresult = netunam (path_ext, login_ext); |
2277 | 2277 |
2278 return netresult == -1 ? Qnil : Qt; | 2278 return netresult == -1 ? Qnil : Qt; |
2279 } | 2279 } |
2322 /* Return nonzero if file FILENAME exists and can be written. */ | 2322 /* Return nonzero if file FILENAME exists and can be written. */ |
2323 | 2323 |
2324 static int | 2324 static int |
2325 check_writable (const Ibyte *filename) | 2325 check_writable (const Ibyte *filename) |
2326 { | 2326 { |
2327 #if defined(WIN32_NATIVE) || defined(CYGWIN) | 2327 #ifdef WIN32_ANY |
2328 #ifdef CYGWIN | 2328 // Since this has to work for a directory, we can't just call 'CreateFile' |
2329 Extbyte filename_buffer[PATH_MAX]; | 2329 PSECURITY_DESCRIPTOR pDesc; /* Must be freed with LocalFree */ |
2330 #endif | 2330 /* these need not be freed, they point into pDesc */ |
2331 // Since this has to work for a directory, we can't just call 'CreateFile' | 2331 PSID psidOwner; |
2332 PSECURITY_DESCRIPTOR pDesc; /* Must be freed with LocalFree */ | 2332 PSID psidGroup; |
2333 /* these need not be freed, they point into pDesc */ | 2333 PACL pDacl; |
2334 PSID psidOwner; | 2334 PACL pSacl; |
2335 PSID psidGroup; | 2335 /* end of insides of descriptor */ |
2336 PACL pDacl; | 2336 DWORD error; |
2337 PACL pSacl; | 2337 DWORD attributes; |
2338 /* end of insides of descriptor */ | 2338 HANDLE tokenHandle; |
2339 DWORD error; | 2339 GENERIC_MAPPING genericMapping; |
2340 DWORD attributes; | 2340 DWORD accessMask; |
2341 HANDLE tokenHandle; | 2341 PRIVILEGE_SET PrivilegeSet; |
2342 GENERIC_MAPPING genericMapping; | 2342 DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET ); |
2343 DWORD accessMask; | 2343 BOOL fAccessGranted = FALSE; |
2344 PRIVILEGE_SET PrivilegeSet; | 2344 DWORD dwAccessAllowed; |
2345 DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET ); | 2345 Extbyte *fnameext; |
2346 BOOL fAccessGranted = FALSE; | 2346 |
2347 DWORD dwAccessAllowed; | 2347 LOCAL_FILE_FORMAT_TO_TSTR (filename, fnameext); |
2348 Extbyte *fnameext; | 2348 |
2349 | 2349 // First check for a normal file with the old-style readonly bit |
2350 C_STRING_TO_TSTR(filename, fnameext); | 2350 attributes = qxeGetFileAttributes(fnameext); |
2351 | 2351 if (FILE_ATTRIBUTE_READONLY == (attributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY))) |
2352 #ifdef CYGWIN | 2352 return 0; |
2353 cygwin_conv_to_full_win32_path(fnameext, filename_buffer); | 2353 |
2354 fnameext = filename_buffer; | 2354 /* Win32 prototype lacks const. */ |
2355 #endif | 2355 error = qxeGetNamedSecurityInfo(fnameext, SE_FILE_OBJECT, |
2356 | 2356 DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, |
2357 // First check for a normal file with the old-style readonly bit | 2357 &psidOwner, &psidGroup, &pDacl, &pSacl, &pDesc); |
2358 if(error != ERROR_SUCCESS) { // FAT? | |
2358 attributes = qxeGetFileAttributes(fnameext); | 2359 attributes = qxeGetFileAttributes(fnameext); |
2359 if (FILE_ATTRIBUTE_READONLY == (attributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY))) | 2360 return (attributes & FILE_ATTRIBUTE_DIRECTORY) || (0 == (attributes & FILE_ATTRIBUTE_READONLY)); |
2361 } | |
2362 | |
2363 genericMapping.GenericRead = FILE_GENERIC_READ; | |
2364 genericMapping.GenericWrite = FILE_GENERIC_WRITE; | |
2365 genericMapping.GenericExecute = FILE_GENERIC_EXECUTE; | |
2366 genericMapping.GenericAll = FILE_ALL_ACCESS; | |
2367 | |
2368 if(!ImpersonateSelf(SecurityDelegation)) { | |
2369 return 0; | |
2370 } | |
2371 if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &tokenHandle)) { | |
2372 return 0; | |
2373 } | |
2374 | |
2375 accessMask = GENERIC_WRITE; | |
2376 MapGenericMask(&accessMask, &genericMapping); | |
2377 | |
2378 if(!AccessCheck(pDesc, tokenHandle, accessMask, &genericMapping, | |
2379 &PrivilegeSet, // receives privileges used in check | |
2380 &dwPrivSetSize, // size of PrivilegeSet buffer | |
2381 &dwAccessAllowed, // receives mask of allowed access rights | |
2382 &fAccessGranted)) | |
2383 { | |
2384 CloseHandle(tokenHandle); | |
2385 RevertToSelf(); | |
2386 LocalFree(pDesc); | |
2360 return 0; | 2387 return 0; |
2361 | 2388 } |
2362 /* Win32 prototype lacks const. */ | 2389 CloseHandle(tokenHandle); |
2363 error = qxeGetNamedSecurityInfo(fnameext, SE_FILE_OBJECT, | 2390 RevertToSelf(); |
2364 DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, | 2391 LocalFree(pDesc); |
2365 &psidOwner, &psidGroup, &pDacl, &pSacl, &pDesc); | 2392 return fAccessGranted == TRUE; |
2366 if(error != ERROR_SUCCESS) { // FAT? | 2393 #elif defined (HAVE_EACCESS) |
2367 attributes = qxeGetFileAttributes(fnameext); | |
2368 return (attributes & FILE_ATTRIBUTE_DIRECTORY) || (0 == (attributes & FILE_ATTRIBUTE_READONLY)); | |
2369 } | |
2370 | |
2371 genericMapping.GenericRead = FILE_GENERIC_READ; | |
2372 genericMapping.GenericWrite = FILE_GENERIC_WRITE; | |
2373 genericMapping.GenericExecute = FILE_GENERIC_EXECUTE; | |
2374 genericMapping.GenericAll = FILE_ALL_ACCESS; | |
2375 | |
2376 if(!ImpersonateSelf(SecurityDelegation)) { | |
2377 return 0; | |
2378 } | |
2379 if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &tokenHandle)) { | |
2380 return 0; | |
2381 } | |
2382 | |
2383 accessMask = GENERIC_WRITE; | |
2384 MapGenericMask(&accessMask, &genericMapping); | |
2385 | |
2386 if(!AccessCheck(pDesc, tokenHandle, accessMask, &genericMapping, | |
2387 &PrivilegeSet, // receives privileges used in check | |
2388 &dwPrivSetSize, // size of PrivilegeSet buffer | |
2389 &dwAccessAllowed, // receives mask of allowed access rights | |
2390 &fAccessGranted)) | |
2391 { | |
2392 CloseHandle(tokenHandle); | |
2393 RevertToSelf(); | |
2394 LocalFree(pDesc); | |
2395 return 0; | |
2396 } | |
2397 CloseHandle(tokenHandle); | |
2398 RevertToSelf(); | |
2399 LocalFree(pDesc); | |
2400 return fAccessGranted == TRUE; | |
2401 #else | |
2402 #ifdef HAVE_EACCESS | |
2403 return (qxe_eaccess (filename, W_OK) >= 0); | 2394 return (qxe_eaccess (filename, W_OK) >= 0); |
2404 #else | 2395 #else |
2405 /* Access isn't quite right because it uses the real uid | 2396 /* Access isn't quite right because it uses the real uid |
2406 and we really want to test with the effective uid. | 2397 and we really want to test with the effective uid. |
2407 But Unix doesn't give us a right way to do it. | 2398 But Unix doesn't give us a right way to do it. |
2408 Opening with O_WRONLY could work for an ordinary file, | 2399 Opening with O_WRONLY could work for an ordinary file, |
2409 but would lose for directories. */ | 2400 but would lose for directories. */ |
2410 return (qxe_access (filename, W_OK) >= 0); | 2401 return (qxe_access (filename, W_OK) >= 0); |
2411 #endif | 2402 #endif /* (not) defined (HAVE_EACCESS) */ |
2412 #endif | |
2413 } | 2403 } |
2414 | 2404 |
2415 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /* | 2405 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /* |
2416 Return t if file FILENAME exists. (This does not mean you can read it.) | 2406 Return t if file FILENAME exists. (This does not mean you can read it.) |
2417 See also `file-readable-p' and `file-attributes'. | 2407 See also `file-readable-p' and `file-attributes'. |