* grp.cc (read_etc_group): On NT, add a line for gid = -1. Change name
"unknown" to "mkgroup". (internal_getgrgid): Do not return default in nontsec case. (internal_getgroups): Add argument srchsid and look for it in groups if not NULL. * passwd.cc (read_etc_passwd): On NT, add a line for uid = -1. Use same default uid for Win95 and NT. Call cygheap_user::ontherange to initialize HOME. * cygheap.cc (init_cygheap::etc_changed): Move to uinfo.cc. * cygheap.h (init_cygheap::etc_changed_h): Remove. (init_cygheap::etc_changed): Ditto. * grp.cc (group_state): Remove. Use gr instead throughout. (gr): Define as class pwdgrp. (read_etc_group): Remove gr definition. Remove calls to set_last_modified and close. Pass add_grp to gr.load to load file. * passwd.cc (passwd_state): Remove. Use pr instead, throughout. (pr): Define as class pwdgrp. (read_etc_passwd): Remove pr definition. Remove calls to set_last_modified and close. Pass add_pwd_line to pr.load to load file. * pwdgrp.h (etc): New helper class for pwdgrp. (pwdgrp): Combine pwdgrp_check and pwdgrp_read into one class. Remove file_w32 and last_modified fields. (pwdgrp::set_last_modified): Remove. (pwdgrp::isinitializing): Remove FindFirstFile stuff. Move to etc::file_changed. (pwdgrp::load): Rename from 'open'. Call etc::init to initialize etc scanning. Close file handle after reading buffer into memory. Parse buffer by calling second argument. (pwdgrp::gets): Reorganize slightly to rely on eptr starting at beginning of buffer. Free buffer when memory exhausted. (pwdgrp::close): Remove. * uinfo.cc (etc::dir_changed): New function. (etc::init): Ditto. (etc::file_changed): Ditto. (etc::set_last_modified): Ditto.
This commit is contained in:
parent
d4d80d8c65
commit
14ea50290a
@ -1,3 +1,46 @@
|
|||||||
|
2003-01-17 Pierre Humblet <pierre.humblet@ieee.org>
|
||||||
|
|
||||||
|
* grp.cc (read_etc_group): On NT, add a line for gid = -1. Change name
|
||||||
|
"unknown" to "mkgroup".
|
||||||
|
(internal_getgrgid): Do not return default in nontsec case.
|
||||||
|
(internal_getgroups): Add argument srchsid and look for it in groups if
|
||||||
|
not NULL.
|
||||||
|
* passwd.cc (read_etc_passwd): On NT, add a line for uid = -1. Use
|
||||||
|
same default uid for Win95 and NT. Call cygheap_user::ontherange to
|
||||||
|
initialize HOME.
|
||||||
|
|
||||||
|
|
||||||
|
2003-01-16 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
|
* cygheap.cc (init_cygheap::etc_changed): Move to uinfo.cc.
|
||||||
|
* cygheap.h (init_cygheap::etc_changed_h): Remove.
|
||||||
|
(init_cygheap::etc_changed): Ditto.
|
||||||
|
* grp.cc (group_state): Remove. Use gr instead throughout.
|
||||||
|
(gr): Define as class pwdgrp.
|
||||||
|
(read_etc_group): Remove gr definition. Remove calls to
|
||||||
|
set_last_modified and close. Pass add_grp to gr.load to load file.
|
||||||
|
* passwd.cc (passwd_state): Remove. Use pr instead, throughout.
|
||||||
|
(pr): Define as class pwdgrp.
|
||||||
|
(read_etc_passwd): Remove pr definition. Remove calls to
|
||||||
|
set_last_modified and close. Pass add_pwd_line to pr.load to load
|
||||||
|
file.
|
||||||
|
* pwdgrp.h (etc): New helper class for pwdgrp.
|
||||||
|
(pwdgrp): Combine pwdgrp_check and pwdgrp_read into one class. Remove
|
||||||
|
file_w32 and last_modified fields.
|
||||||
|
(pwdgrp::set_last_modified): Remove.
|
||||||
|
(pwdgrp::isinitializing): Remove FindFirstFile stuff. Move to
|
||||||
|
etc::file_changed.
|
||||||
|
(pwdgrp::load): Rename from 'open'. Call etc::init to initialize etc
|
||||||
|
scanning. Close file handle after reading buffer into memory. Parse
|
||||||
|
buffer by calling second argument.
|
||||||
|
(pwdgrp::gets): Reorganize slightly to rely on eptr starting at
|
||||||
|
beginning of buffer. Free buffer when memory exhausted.
|
||||||
|
(pwdgrp::close): Remove.
|
||||||
|
* uinfo.cc (etc::dir_changed): New function.
|
||||||
|
(etc::init): Ditto.
|
||||||
|
(etc::file_changed): Ditto.
|
||||||
|
(etc::set_last_modified): Ditto.
|
||||||
|
|
||||||
2003-01-16 Jason Tishler <jason@tishler.net>
|
2003-01-16 Jason Tishler <jason@tishler.net>
|
||||||
|
|
||||||
* mmap.cc (fixup_mmaps_after_fork): Add ERROR_NOACCESS to the list of
|
* mmap.cc (fixup_mmaps_after_fork): Add ERROR_NOACCESS to the list of
|
||||||
|
@ -380,39 +380,6 @@ cstrdup1 (const char *s)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
init_cygheap::etc_changed ()
|
|
||||||
{
|
|
||||||
bool res = 0;
|
|
||||||
|
|
||||||
if (!etc_changed_h)
|
|
||||||
{
|
|
||||||
path_conv pwd ("/etc");
|
|
||||||
etc_changed_h = FindFirstChangeNotification (pwd, FALSE,
|
|
||||||
FILE_NOTIFY_CHANGE_LAST_WRITE);
|
|
||||||
if (etc_changed_h == INVALID_HANDLE_VALUE)
|
|
||||||
system_printf ("Can't open /etc for checking, %E", (char *) pwd,
|
|
||||||
etc_changed_h);
|
|
||||||
else if (!DuplicateHandle (hMainProc, etc_changed_h, hMainProc,
|
|
||||||
&etc_changed_h, 0, TRUE,
|
|
||||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
|
||||||
{
|
|
||||||
system_printf ("Can't inherit /etc handle, %E", (char *) pwd,
|
|
||||||
etc_changed_h);
|
|
||||||
etc_changed_h = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (etc_changed_h != INVALID_HANDLE_VALUE
|
|
||||||
&& WaitForSingleObject (etc_changed_h, 0) == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
(void) FindNextChangeNotification (etc_changed_h);
|
|
||||||
res = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cygheap_root::set (const char *posix, const char *native)
|
cygheap_root::set (const char *posix, const char *native)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygheap.h: Cygwin heap manager.
|
/* cygheap.h: Cygwin heap manager.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002 Red Hat, Inc.
|
Copyright 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -216,15 +216,12 @@ struct init_cygheap
|
|||||||
mode_t umask;
|
mode_t umask;
|
||||||
HANDLE shared_h;
|
HANDLE shared_h;
|
||||||
HANDLE console_h;
|
HANDLE console_h;
|
||||||
HANDLE etc_changed_h;
|
|
||||||
char *cygwin_regname;
|
char *cygwin_regname;
|
||||||
cwdstuff cwd;
|
cwdstuff cwd;
|
||||||
dtable fdtab;
|
dtable fdtab;
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
cygheap_debug debug;
|
cygheap_debug debug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool etc_changed ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CYGHEAPSIZE (sizeof (init_cygheap) + (16000 * sizeof (fhandler_union)) + (4 * 65536))
|
#define CYGHEAPSIZE (sizeof (init_cygheap) + (16000 * sizeof (fhandler_union)) + (4 * 65536))
|
||||||
|
@ -40,8 +40,8 @@ static int max_lines;
|
|||||||
static int grp_pos = 0;
|
static int grp_pos = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static pwdgrp_check group_state;
|
static pwdgrp gr;
|
||||||
static char * NO_COPY null_ptr = NULL;
|
static char * NO_COPY null_ptr;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_grp (struct __group32 &grp, char *line)
|
parse_grp (struct __group32 &grp, char *line)
|
||||||
@ -129,35 +129,24 @@ pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INIT
|
|||||||
static void
|
static void
|
||||||
read_etc_group ()
|
read_etc_group ()
|
||||||
{
|
{
|
||||||
static pwdgrp_read gr;
|
|
||||||
|
|
||||||
group_lock here (cygwin_finished_initializing);
|
group_lock here (cygwin_finished_initializing);
|
||||||
|
|
||||||
/* if we got blocked by the mutex, then etc_group may have been processed */
|
/* if we got blocked by the mutex, then etc_group may have been processed */
|
||||||
if (group_state.isinitializing ())
|
if (gr.isinitializing ())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < curr_lines; i++)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
if ((group_buf + i)->gr_mem != &null_ptr)
|
if ((group_buf + i)->gr_mem != &null_ptr)
|
||||||
free ((group_buf + i)->gr_mem);
|
free ((group_buf + i)->gr_mem);
|
||||||
|
|
||||||
curr_lines = 0;
|
curr_lines = 0;
|
||||||
if (gr.open ("/etc/group"))
|
if (!gr.load ("/etc/group", add_grp_line))
|
||||||
{
|
debug_printf ("gr.load failed");
|
||||||
char *line;
|
|
||||||
while ((line = gr.gets ()) != NULL)
|
|
||||||
add_grp_line (line);
|
|
||||||
|
|
||||||
group_state.set_last_modified (gr.get_fhandle (), gr.get_fname ());
|
|
||||||
gr.close ();
|
|
||||||
debug_printf ("Read /etc/group, %d lines", curr_lines);
|
|
||||||
}
|
|
||||||
group_state = loaded;
|
|
||||||
|
|
||||||
/* Complete /etc/group in memory if needed */
|
/* Complete /etc/group in memory if needed */
|
||||||
if (!internal_getgrgid (myself->gid))
|
if (!internal_getgrgid (myself->gid))
|
||||||
{
|
{
|
||||||
static char linebuf [200];
|
static char linebuf [200];
|
||||||
char group_name [UNLEN + 1] = "unknown";
|
char group_name [UNLEN + 1] = "mkgroup";
|
||||||
char strbuf[128] = "";
|
char strbuf[128] = "";
|
||||||
|
|
||||||
if (wincap.has_security ())
|
if (wincap.has_security ())
|
||||||
@ -173,6 +162,9 @@ read_etc_group ()
|
|||||||
debug_printf ("Completing /etc/group: %s", linebuf);
|
debug_printf ("Completing /etc/group: %s", linebuf);
|
||||||
add_grp_line (linebuf);
|
add_grp_line (linebuf);
|
||||||
}
|
}
|
||||||
|
static char pretty_ls[] = "????????::-1:";
|
||||||
|
if (wincap.has_security ())
|
||||||
|
add_grp_line (pretty_ls);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -182,7 +174,7 @@ internal_getgrsid (cygsid &sid)
|
|||||||
{
|
{
|
||||||
char sid_string[128];
|
char sid_string[128];
|
||||||
|
|
||||||
if (group_state.isuninitialized ())
|
if (gr.isuninitialized ())
|
||||||
read_etc_group ();
|
read_etc_group ();
|
||||||
|
|
||||||
if (sid.string (sid_string))
|
if (sid.string (sid_string))
|
||||||
@ -195,27 +187,19 @@ internal_getgrsid (cygsid &sid)
|
|||||||
struct __group32 *
|
struct __group32 *
|
||||||
internal_getgrgid (__gid32_t gid, BOOL check)
|
internal_getgrgid (__gid32_t gid, BOOL check)
|
||||||
{
|
{
|
||||||
struct __group32 * default_grp = NULL;
|
if (gr.isuninitialized () || (check && gr.isinitializing ()))
|
||||||
|
|
||||||
if (group_state.isuninitialized ()
|
|
||||||
|| (check && group_state.isinitializing ()))
|
|
||||||
read_etc_group ();
|
read_etc_group ();
|
||||||
|
|
||||||
for (int i = 0; i < curr_lines; i++)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
{
|
if (group_buf[i].gr_gid == gid)
|
||||||
if (group_buf[i].gr_gid == myself->gid)
|
return group_buf + i;
|
||||||
default_grp = group_buf + i;
|
return NULL;
|
||||||
if (group_buf[i].gr_gid == gid)
|
|
||||||
return group_buf + i;
|
|
||||||
}
|
|
||||||
return allow_ntsec || gid != ILLEGAL_GID ? NULL : default_grp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __group32 *
|
struct __group32 *
|
||||||
internal_getgrnam (const char *name, BOOL check)
|
internal_getgrnam (const char *name, BOOL check)
|
||||||
{
|
{
|
||||||
if (group_state.isuninitialized ()
|
if (gr.isuninitialized () || (check && gr.isinitializing ()))
|
||||||
|| (check && group_state.isinitializing ()))
|
|
||||||
read_etc_group ();
|
read_etc_group ();
|
||||||
|
|
||||||
for (int i = 0; i < curr_lines; i++)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
@ -280,7 +264,7 @@ endgrent ()
|
|||||||
extern "C" struct __group32 *
|
extern "C" struct __group32 *
|
||||||
getgrent32 ()
|
getgrent32 ()
|
||||||
{
|
{
|
||||||
if (group_state.isinitializing ())
|
if (gr.isinitializing ())
|
||||||
read_etc_group ();
|
read_etc_group ();
|
||||||
|
|
||||||
if (grp_pos < curr_lines)
|
if (grp_pos < curr_lines)
|
||||||
@ -307,7 +291,7 @@ setgrent ()
|
|||||||
struct __group32 *
|
struct __group32 *
|
||||||
internal_getgrent (int pos)
|
internal_getgrent (int pos)
|
||||||
{
|
{
|
||||||
if (group_state.isuninitialized ())
|
if (gr.isuninitialized ())
|
||||||
read_etc_group ();
|
read_etc_group ();
|
||||||
|
|
||||||
if (pos < curr_lines)
|
if (pos < curr_lines)
|
||||||
@ -316,7 +300,7 @@ internal_getgrent (int pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
internal_getgroups (int gidsetsize, __gid32_t *grouplist)
|
internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygsid * srchsid)
|
||||||
{
|
{
|
||||||
HANDLE hToken = NULL;
|
HANDLE hToken = NULL;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
@ -345,6 +329,13 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist)
|
|||||||
{
|
{
|
||||||
cygsid sid;
|
cygsid sid;
|
||||||
|
|
||||||
|
if (srchsid)
|
||||||
|
{
|
||||||
|
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
||||||
|
if (*srchsid == groups->Groups[pg].Sid)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
|
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
|
||||||
if (sid.getfromgr (gr))
|
if (sid.getfromgr (gr))
|
||||||
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
||||||
|
@ -30,8 +30,7 @@ static struct passwd *passwd_buf; /* passwd contents in memory */
|
|||||||
static int curr_lines;
|
static int curr_lines;
|
||||||
static int max_lines;
|
static int max_lines;
|
||||||
|
|
||||||
static pwdgrp_check passwd_state;
|
static pwdgrp pr;
|
||||||
|
|
||||||
|
|
||||||
/* Position in the passwd cache */
|
/* Position in the passwd cache */
|
||||||
#ifdef _MT_SAFE
|
#ifdef _MT_SAFE
|
||||||
@ -40,7 +39,7 @@ static pwdgrp_check passwd_state;
|
|||||||
static int pw_pos = 0;
|
static int pw_pos = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove a : teminated string from the buffer, and increment the pointer */
|
/* Remove a : terminated string from the buffer, and increment the pointer */
|
||||||
static char *
|
static char *
|
||||||
grab_string (char **p)
|
grab_string (char **p)
|
||||||
{
|
{
|
||||||
@ -122,48 +121,37 @@ class passwd_lock
|
|||||||
pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
/* Read in /etc/passwd and save contents in the password cache.
|
/* Read in /etc/passwd and save contents in the password cache.
|
||||||
This sets passwd_state to loaded or emulated so functions in this file can
|
This sets pr to loaded or emulated so functions in this file can
|
||||||
tell that /etc/passwd has been read in or will be emulated. */
|
tell that /etc/passwd has been read in or will be emulated. */
|
||||||
static void
|
static void
|
||||||
read_etc_passwd ()
|
read_etc_passwd ()
|
||||||
{
|
{
|
||||||
static pwdgrp_read pr;
|
|
||||||
|
|
||||||
/* A mutex is ok for speed here - pthreads will use critical sections not
|
/* A mutex is ok for speed here - pthreads will use critical sections not
|
||||||
* mutexes for non-shared mutexes in the future. Also, this function will
|
* mutexes for non-shared mutexes in the future. Also, this function will
|
||||||
* at most be called once from each thread, after that the passwd_state
|
* at most be called once from each thread, after that the pr
|
||||||
* test will succeed */
|
* test will succeed */
|
||||||
passwd_lock here (cygwin_finished_initializing);
|
passwd_lock here (cygwin_finished_initializing);
|
||||||
|
|
||||||
/* if we got blocked by the mutex, then etc_passwd may have been processed */
|
/* if we got blocked by the mutex, then etc_passwd may have been processed */
|
||||||
if (passwd_state.isinitializing ())
|
if (pr.isinitializing ())
|
||||||
{
|
{
|
||||||
curr_lines = 0;
|
curr_lines = 0;
|
||||||
if (pr.open ("/etc/passwd"))
|
if (!pr.load ("/etc/passwd", add_pwd_line))
|
||||||
{
|
debug_printf ("pr.load failed");
|
||||||
char *line;
|
|
||||||
while ((line = pr.gets ()) != NULL)
|
|
||||||
add_pwd_line (line);
|
|
||||||
|
|
||||||
passwd_state.set_last_modified (pr.get_fhandle (), pr.get_fname ());
|
|
||||||
pr.close ();
|
|
||||||
debug_printf ("Read /etc/passwd, %d lines", curr_lines);
|
|
||||||
}
|
|
||||||
passwd_state = loaded;
|
|
||||||
|
|
||||||
static char linebuf[1024];
|
static char linebuf[1024];
|
||||||
char strbuf[128] = "";
|
char strbuf[128] = "";
|
||||||
BOOL searchentry = TRUE;
|
BOOL searchentry = TRUE;
|
||||||
__uid32_t default_uid = DEFAULT_UID;
|
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
if (wincap.has_security ())
|
if (wincap.has_security ())
|
||||||
{
|
{
|
||||||
|
static char pretty_ls[] = "????????:*:-1:-1:";
|
||||||
|
add_pwd_line (pretty_ls);
|
||||||
cygsid tu = cygheap->user.sid ();
|
cygsid tu = cygheap->user.sid ();
|
||||||
tu.string (strbuf);
|
tu.string (strbuf);
|
||||||
if (myself->uid == ILLEGAL_UID
|
if (myself->uid == ILLEGAL_UID)
|
||||||
&& (searchentry = !internal_getpwsid (tu)))
|
searchentry = !internal_getpwsid (tu);
|
||||||
default_uid = DEFAULT_UID_NT;
|
|
||||||
}
|
}
|
||||||
else if (myself->uid == ILLEGAL_UID)
|
else if (myself->uid == ILLEGAL_UID)
|
||||||
searchentry = !internal_getpwuid (DEFAULT_UID);
|
searchentry = !internal_getpwuid (DEFAULT_UID);
|
||||||
@ -173,11 +161,12 @@ read_etc_passwd ()
|
|||||||
myself->uid != (__uid32_t) pw->pw_uid &&
|
myself->uid != (__uid32_t) pw->pw_uid &&
|
||||||
!internal_getpwuid (myself->uid))))
|
!internal_getpwuid (myself->uid))))
|
||||||
{
|
{
|
||||||
|
(void) cygheap->user.ontherange (CH_HOME, NULL);
|
||||||
snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh",
|
snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh",
|
||||||
cygheap->user.name (),
|
cygheap->user.name (),
|
||||||
myself->uid == ILLEGAL_UID ? default_uid : myself->uid,
|
myself->uid == ILLEGAL_UID ? DEFAULT_UID_NT : myself->uid,
|
||||||
myself->gid,
|
myself->gid,
|
||||||
strbuf, getenv ("HOME") ?: "/");
|
strbuf, getenv ("HOME") ?: "");
|
||||||
debug_printf ("Completing /etc/passwd: %s", linebuf);
|
debug_printf ("Completing /etc/passwd: %s", linebuf);
|
||||||
add_pwd_line (linebuf);
|
add_pwd_line (linebuf);
|
||||||
}
|
}
|
||||||
@ -192,7 +181,7 @@ internal_getpwsid (cygsid &sid)
|
|||||||
char *ptr1, *ptr2, *endptr;
|
char *ptr1, *ptr2, *endptr;
|
||||||
char sid_string[128] = {0,','};
|
char sid_string[128] = {0,','};
|
||||||
|
|
||||||
if (passwd_state.isuninitialized ())
|
if (pr.isuninitialized ())
|
||||||
read_etc_passwd ();
|
read_etc_passwd ();
|
||||||
|
|
||||||
if (sid.string (sid_string + 2))
|
if (sid.string (sid_string + 2))
|
||||||
@ -211,8 +200,8 @@ internal_getpwsid (cygsid &sid)
|
|||||||
struct passwd *
|
struct passwd *
|
||||||
internal_getpwuid (__uid32_t uid, BOOL check)
|
internal_getpwuid (__uid32_t uid, BOOL check)
|
||||||
{
|
{
|
||||||
if (passwd_state.isuninitialized ()
|
if (pr.isuninitialized ()
|
||||||
|| (check && passwd_state.isinitializing ()))
|
|| (check && pr.isinitializing ()))
|
||||||
read_etc_passwd ();
|
read_etc_passwd ();
|
||||||
|
|
||||||
for (int i = 0; i < curr_lines; i++)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
@ -224,8 +213,8 @@ internal_getpwuid (__uid32_t uid, BOOL check)
|
|||||||
struct passwd *
|
struct passwd *
|
||||||
internal_getpwnam (const char *name, BOOL check)
|
internal_getpwnam (const char *name, BOOL check)
|
||||||
{
|
{
|
||||||
if (passwd_state.isuninitialized ()
|
if (pr.isuninitialized ()
|
||||||
|| (check && passwd_state.isinitializing ()))
|
|| (check && pr.isinitializing ()))
|
||||||
read_etc_passwd ();
|
read_etc_passwd ();
|
||||||
|
|
||||||
for (int i = 0; i < curr_lines; i++)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
@ -347,7 +336,7 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s
|
|||||||
extern "C" struct passwd *
|
extern "C" struct passwd *
|
||||||
getpwent (void)
|
getpwent (void)
|
||||||
{
|
{
|
||||||
if (passwd_state.isinitializing ())
|
if (pr.isinitializing ())
|
||||||
read_etc_passwd ();
|
read_etc_passwd ();
|
||||||
|
|
||||||
if (pw_pos < curr_lines)
|
if (pw_pos < curr_lines)
|
||||||
@ -390,7 +379,7 @@ getpass (const char * prompt)
|
|||||||
#endif
|
#endif
|
||||||
struct termios ti, newti;
|
struct termios ti, newti;
|
||||||
|
|
||||||
if (passwd_state.isinitializing ())
|
if (pr.isinitializing ())
|
||||||
read_etc_passwd ();
|
read_etc_passwd ();
|
||||||
|
|
||||||
cygheap_fdget fhstdin (0);
|
cygheap_fdget fhstdin (0);
|
||||||
|
@ -19,7 +19,7 @@ extern struct __group32 *internal_getgrsid (cygsid &);
|
|||||||
extern struct __group32 *internal_getgrgid (__gid32_t gid, BOOL = FALSE);
|
extern struct __group32 *internal_getgrgid (__gid32_t gid, BOOL = FALSE);
|
||||||
extern struct __group32 *internal_getgrnam (const char *, BOOL = FALSE);
|
extern struct __group32 *internal_getgrnam (const char *, BOOL = FALSE);
|
||||||
extern struct __group32 *internal_getgrent (int);
|
extern struct __group32 *internal_getgrent (int);
|
||||||
int internal_getgroups (int, __gid32_t *);
|
int internal_getgroups (int, __gid32_t *, cygsid * = NULL);
|
||||||
|
|
||||||
enum pwdgrp_state {
|
enum pwdgrp_state {
|
||||||
uninitialized = 0,
|
uninitialized = 0,
|
||||||
@ -27,111 +27,107 @@ enum pwdgrp_state {
|
|||||||
loaded
|
loaded
|
||||||
};
|
};
|
||||||
|
|
||||||
class pwdgrp_check {
|
#define MAX_ETC_FILES 2
|
||||||
pwdgrp_state state;
|
class etc
|
||||||
FILETIME last_modified;
|
{
|
||||||
char file_w32[MAX_PATH];
|
static int curr_ix;
|
||||||
|
static bool sawchange[MAX_ETC_FILES];
|
||||||
|
static const char *fn[MAX_ETC_FILES];
|
||||||
|
static FILETIME last_modified[MAX_ETC_FILES];
|
||||||
|
static bool dir_changed (int);
|
||||||
|
static int init (int, const char *);
|
||||||
|
static bool file_changed (int);
|
||||||
|
static void set_last_modified (int, FILETIME&);
|
||||||
|
friend class pwdgrp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class pwdgrp
|
||||||
|
{
|
||||||
|
pwdgrp_state state;
|
||||||
|
int pwd_ix;
|
||||||
|
path_conv pc;
|
||||||
|
char *buf;
|
||||||
|
char *lptr, *eptr;
|
||||||
|
|
||||||
|
char *gets ()
|
||||||
|
{
|
||||||
|
if (!buf)
|
||||||
|
lptr = NULL;
|
||||||
|
else if (!eptr)
|
||||||
|
lptr = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lptr = eptr;
|
||||||
|
eptr = strchr (lptr, '\n');
|
||||||
|
if (eptr)
|
||||||
|
{
|
||||||
|
if (eptr > lptr && *(eptr - 1) == '\r')
|
||||||
|
*(eptr - 1) = 0;
|
||||||
|
*eptr++ = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lptr;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pwdgrp_check () : state (uninitialized) {}
|
pwdgrp () : state (uninitialized) {}
|
||||||
BOOL isinitializing ()
|
BOOL isinitializing ()
|
||||||
{
|
{
|
||||||
if (state <= initializing)
|
if (state <= initializing)
|
||||||
state = initializing;
|
state = initializing;
|
||||||
else if (cygheap->etc_changed ())
|
else if (etc::file_changed (pwd_ix - 1))
|
||||||
{
|
state = initializing;
|
||||||
if (!file_w32[0])
|
|
||||||
state = initializing;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HANDLE h;
|
|
||||||
WIN32_FIND_DATA data;
|
|
||||||
|
|
||||||
if ((h = FindFirstFile (file_w32, &data)) != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0)
|
|
||||||
state = initializing;
|
|
||||||
FindClose (h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state == initializing;
|
return state == initializing;
|
||||||
}
|
}
|
||||||
void operator = (pwdgrp_state nstate)
|
void operator = (pwdgrp_state nstate) { state = nstate; }
|
||||||
{
|
|
||||||
state = nstate;
|
|
||||||
}
|
|
||||||
BOOL isuninitialized () const { return state == uninitialized; }
|
BOOL isuninitialized () const { return state == uninitialized; }
|
||||||
void set_last_modified (HANDLE fh, const char *name)
|
|
||||||
{
|
|
||||||
if (!file_w32[0])
|
|
||||||
strcpy (file_w32, name);
|
|
||||||
GetFileTime (fh, NULL, NULL, &last_modified);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class pwdgrp_read {
|
bool load (const char *posix_fname, void (* add_line) (char *))
|
||||||
path_conv pc;
|
|
||||||
HANDLE fh;
|
|
||||||
char *buf;
|
|
||||||
char *lptr, *eptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool open (const char *posix_fname)
|
|
||||||
{
|
{
|
||||||
if (buf)
|
if (buf)
|
||||||
free (buf);
|
free (buf);
|
||||||
buf = lptr = eptr = NULL;
|
buf = lptr = eptr = NULL;
|
||||||
|
|
||||||
pc.check (posix_fname);
|
pc.check (posix_fname);
|
||||||
if (pc.error || !pc.exists () || !pc.isdisk () || pc.isdir ())
|
pwd_ix = etc::init (pwd_ix - 1, pc) + 1;
|
||||||
return false;
|
|
||||||
|
|
||||||
fh = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL, OPEN_EXISTING,
|
paranoid_printf ("%s", posix_fname);
|
||||||
FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
if (fh != INVALID_HANDLE_VALUE)
|
bool res;
|
||||||
{
|
if (pc.error || !pc.exists () || !pc.isdisk () || pc.isdir ())
|
||||||
DWORD size = GetFileSize (fh, NULL), read_bytes;
|
res = false;
|
||||||
buf = (char *) malloc (size + 1);
|
|
||||||
if (!ReadFile (fh, buf, size, &read_bytes, NULL))
|
|
||||||
{
|
|
||||||
if (buf)
|
|
||||||
free (buf);
|
|
||||||
buf = NULL;
|
|
||||||
CloseHandle (fh);
|
|
||||||
fh = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
buf[read_bytes] = '\0';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
char *gets ()
|
|
||||||
{
|
|
||||||
if (!buf)
|
|
||||||
return NULL;
|
|
||||||
if (!lptr)
|
|
||||||
lptr = buf;
|
|
||||||
else if (!eptr)
|
|
||||||
return lptr = NULL;
|
|
||||||
else
|
else
|
||||||
lptr = eptr;
|
|
||||||
eptr = strchr (lptr, '\n');
|
|
||||||
if (eptr)
|
|
||||||
{
|
{
|
||||||
if (eptr > lptr && *(eptr - 1) == '\r')
|
HANDLE fh = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL,
|
||||||
*(eptr - 1) = 0;
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
*eptr++ = '\0';
|
if (fh == INVALID_HANDLE_VALUE)
|
||||||
|
res = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD size = GetFileSize (fh, NULL), read_bytes;
|
||||||
|
buf = (char *) malloc (size + 1);
|
||||||
|
if (!ReadFile (fh, buf, size, &read_bytes, NULL))
|
||||||
|
{
|
||||||
|
if (buf)
|
||||||
|
free (buf);
|
||||||
|
buf = NULL;
|
||||||
|
fh = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buf[read_bytes] = '\0';
|
||||||
|
eptr = buf;
|
||||||
|
CloseHandle (fh);
|
||||||
|
FILETIME ft;
|
||||||
|
if (GetFileTime (fh, NULL, NULL, &ft))
|
||||||
|
etc::set_last_modified (pwd_ix - 1, ft);
|
||||||
|
char *line;
|
||||||
|
while ((line = gets()) != NULL)
|
||||||
|
add_line (line);
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return lptr;
|
|
||||||
}
|
state = loaded;
|
||||||
inline HANDLE get_fhandle () { return fh; }
|
return res;
|
||||||
inline const char *get_fname () { return pc; }
|
|
||||||
void close ()
|
|
||||||
{
|
|
||||||
if (fh)
|
|
||||||
CloseHandle (fh);
|
|
||||||
fh = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -389,3 +389,88 @@ cygheap_user::env_name (const char *name, size_t namelen)
|
|||||||
(void) domain ();
|
(void) domain ();
|
||||||
return pwinname;
|
return pwinname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NO_COPY etc::curr_ix = -1;
|
||||||
|
bool NO_COPY etc::sawchange[MAX_ETC_FILES];
|
||||||
|
const NO_COPY char *etc::fn[MAX_ETC_FILES];
|
||||||
|
FILETIME NO_COPY etc::last_modified[MAX_ETC_FILES];
|
||||||
|
|
||||||
|
int
|
||||||
|
etc::init (int n, const char *etc_fn)
|
||||||
|
{
|
||||||
|
if (n >= 0)
|
||||||
|
/* ok */;
|
||||||
|
else if (++curr_ix < MAX_ETC_FILES)
|
||||||
|
n = curr_ix;
|
||||||
|
else
|
||||||
|
api_fatal ("internal error");
|
||||||
|
|
||||||
|
fn[n] = etc_fn;
|
||||||
|
sawchange[n] = false;
|
||||||
|
paranoid_printf ("curr_ix %d, n %d", curr_ix, n);
|
||||||
|
return curr_ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
etc::dir_changed (int n)
|
||||||
|
{
|
||||||
|
bool res = sawchange[n];
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
static HANDLE NO_COPY changed_h;
|
||||||
|
if (!changed_h)
|
||||||
|
{
|
||||||
|
path_conv pwd ("/etc");
|
||||||
|
changed_h = FindFirstChangeNotification (pwd, FALSE,
|
||||||
|
FILE_NOTIFY_CHANGE_LAST_WRITE);
|
||||||
|
if (changed_h == INVALID_HANDLE_VALUE)
|
||||||
|
system_printf ("Can't open /etc for checking, %E", (char *) pwd,
|
||||||
|
changed_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed_h == INVALID_HANDLE_VALUE)
|
||||||
|
res = true;
|
||||||
|
else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
(void) FindNextChangeNotification (changed_h);
|
||||||
|
memset (sawchange, true, sizeof sawchange);
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paranoid_printf ("%s res %d", fn[n], res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
etc::file_changed (int n)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
if (!fn[n])
|
||||||
|
res = true;
|
||||||
|
else if (dir_changed (n))
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
WIN32_FIND_DATA data;
|
||||||
|
|
||||||
|
if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE)
|
||||||
|
res = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FindClose (h);
|
||||||
|
if (CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0)
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sawchange[n] = false;
|
||||||
|
paranoid_printf ("%s res %d", fn[n], res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
etc::set_last_modified (int n, FILETIME& ft)
|
||||||
|
{
|
||||||
|
last_modified[n] = ft;
|
||||||
|
sawchange[n] = false;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user