Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/grp.cc69
-rw-r--r--winsup/cygwin/passwd.cc105
-rw-r--r--winsup/cygwin/pwdgrp.h79
4 files changed, 164 insertions, 105 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index d4722d5b3..95f7d5efd 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+2002-06-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (etc_group): Removed.
+ (parse_grp): Make line parameter nonconst. Don't copy data into new
+ allocated memory. Check for CR instead of LF to accomodate new
+ read method.
+ (add_grp_line): Make line parameter nonconst.
+ (read_etc_group): Rearrange using new pwdgrp_read class.
+ * passwd.cc (parse_pwd): Don't copy data into new allocated memory.
+ Check for CR instead of LF to accomodate new read method.
+ (read_etc_passwd): Rearrange using new pwdgrp_read class.
+ * pwdgrp.h (pwdgrp_check::set_last_modified): Use different
+ parameters.
+ (class pwdgrp_read): New class for opening and reading passwd and
+ group files.
+
2002-06-04 Christopher Faylor <cgf@redhat.com>
* dtable.cc (handle_to_fn): Attempt to handle "raw" accesses to remote
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index 3511bcb92..13f74dd64 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -29,7 +29,6 @@ details. */
/* Read /etc/group only once for better performance. This is done
on the first call that needs information from it. */
-static const char *etc_group NO_COPY = "/etc/group";
static struct __group32 *group_buf; /* group contents in memory */
static int curr_lines;
static int max_lines;
@@ -44,22 +43,19 @@ static int grp_pos = 0;
static pwdgrp_check group_state;
static int
-parse_grp (struct __group32 &grp, const char *line)
+parse_grp (struct __group32 &grp, char *line)
{
int len = strlen(line);
- char *newline = (char *) malloc (len + 1);
- (void) memcpy (newline, line, len + 1);
+ if (line[--len] == '\r')
+ line[len] = '\0';
- if (newline[--len] == '\n')
- newline[len] = '\0';
-
- char *dp = strchr (newline, ':');
+ char *dp = strchr (line, ':');
if (!dp)
return 0;
*dp++ = '\0';
- grp.gr_name = newline;
+ grp.gr_name = line;
grp.gr_passwd = dp;
dp = strchr (grp.gr_passwd, ':');
@@ -104,7 +100,7 @@ parse_grp (struct __group32 &grp, const char *line)
/* Read one line from /etc/group into the group cache */
static void
-add_grp_line (const char *line)
+add_grp_line (char *line)
{
if (curr_lines == max_lines)
{
@@ -143,11 +139,7 @@ pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INIT
void
read_etc_group ()
{
- char linebuf [200];
- char group_name [UNLEN + 1];
- DWORD group_name_len = UNLEN + 1;
-
- strncpy (group_name, "Administrators", sizeof (group_name));
+ static pwdgrp_read gr;
group_lock here (cygwin_finished_initializing);
@@ -158,49 +150,38 @@ read_etc_group ()
if (group_state != initializing)
{
group_state = initializing;
- if (max_lines) /* When rereading, free allocated memory first. */
- {
- for (int i = 0; i < curr_lines; ++i)
- {
- free (group_buf[i].gr_name);
- free (group_buf[i].gr_mem);
- }
- curr_lines = 0;
- }
-
- FILE *f = fopen (etc_group, "rt");
-
- if (f)
+ if (gr.open ("/etc/group"))
{
- while (fgets (linebuf, sizeof (linebuf), f) != NULL)
- {
- if (strlen (linebuf))
- add_grp_line (linebuf);
- }
+ char *line;
+ while ((line = gr.gets ()) != NULL)
+ if (strlen (line))
+ add_grp_line (line);
- group_state.set_last_modified (f);
- fclose (f);
+ group_state.set_last_modified (gr.get_fhandle(), gr.get_fname ());
group_state = loaded;
+ gr.close ();
+ debug_printf ("Read /etc/group, %d lines", curr_lines);
}
else /* /etc/group doesn't exist -- create default one in memory */
{
+ char group_name [UNLEN + 1];
+ DWORD group_name_len = UNLEN + 1;
char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1];
DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
SID_NAME_USE acType;
+ static char linebuf [200];
+
debug_printf ("Emulating /etc/group");
- if (! LookupAccountSidA (NULL ,
- well_known_admins_sid,
- group_name,
- &group_name_len,
- domain_name,
- &domain_name_len,
- &acType))
+ strncpy (group_name, "Administrators", sizeof (group_name));
+ if (! LookupAccountSidA (NULL, well_known_admins_sid, group_name,
+ &group_name_len, domain_name,
+ &domain_name_len, &acType))
{
strcpy (group_name, "unknown");
debug_printf ("Failed to get local admins group name. %E");
}
-
- snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name, (unsigned) DEFAULT_GID);
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name,
+ (unsigned) DEFAULT_GID);
add_grp_line (linebuf);
group_state = emulated;
}
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index efc73f52e..ac1ecf8f0 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -80,19 +80,17 @@ parse_pwd (struct passwd &res, char *buf)
/* Allocate enough room for the passwd struct and all the strings
in it in one go */
size_t len = strlen (buf);
- char *mybuf = (char *) malloc (len + 1);
- (void) memcpy (mybuf, buf, len + 1);
- if (mybuf[--len] == '\n')
- mybuf[len] = '\0';
-
- res.pw_name = grab_string (&mybuf);
- res.pw_passwd = grab_string (&mybuf);
- res.pw_uid = grab_int (&mybuf);
- res.pw_gid = grab_int (&mybuf);
+ if (buf[--len] == '\r')
+ buf[len] = '\0';
+
+ res.pw_name = grab_string (&buf);
+ res.pw_passwd = grab_string (&buf);
+ res.pw_uid = grab_int (&buf);
+ res.pw_gid = grab_int (&buf);
res.pw_comment = 0;
- res.pw_gecos = grab_string (&mybuf);
- res.pw_dir = grab_string (&mybuf);
- res.pw_shell = grab_string (&mybuf);
+ res.pw_gecos = grab_string (&buf);
+ res.pw_dir = grab_string (&buf);
+ res.pw_shell = grab_string (&buf);
}
/* Add one line from /etc/passwd into the password cache */
@@ -133,51 +131,46 @@ pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INI
void
read_etc_passwd ()
{
- char linebuf[1024];
- /* A mutex is ok for speed here - pthreads will use critical sections not mutex's
- * for non-shared mutexs in the future. Also, this function will at most be called
- * once from each thread, after that the passwd_state test will succeed
- */
- passwd_lock here (cygwin_finished_initializing);
-
- /* if we got blocked by the mutex, then etc_passwd may have been processed */
- if (passwd_state != uninitialized)
- return;
-
- if (passwd_state != initializing)
- {
- passwd_state = initializing;
- if (max_lines) /* When rereading, free allocated memory first. */
- {
- for (int i = 0; i < curr_lines; ++i)
- free (passwd_buf[i].pw_name);
- curr_lines = 0;
- }
-
- FILE *f = fopen ("/etc/passwd", "rt");
-
- if (f)
- {
- while (fgets (linebuf, sizeof (linebuf), f) != NULL)
- {
- if (strlen (linebuf))
- add_pwd_line (linebuf);
- }
-
- passwd_state.set_last_modified (f);
- fclose (f);
- passwd_state = loaded;
- }
- else
- {
- debug_printf ("Emulating /etc/passwd");
- snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", cygheap->user.name (),
- (unsigned) DEFAULT_UID, (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/");
- add_pwd_line (linebuf);
- passwd_state = emulated;
- }
+ static pwdgrp_read pr;
- }
+ /* 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
+ * at most be called once from each thread, after that the passwd_state
+ * test will succeed */
+ passwd_lock here (cygwin_finished_initializing);
+
+ /* if we got blocked by the mutex, then etc_passwd may have been processed */
+ if (passwd_state != uninitialized)
+ return;
+
+ if (passwd_state != initializing)
+ {
+ passwd_state = initializing;
+ if (pr.open ("/etc/passwd"))
+ {
+ char *line;
+ while ((line = pr.gets ()) != NULL)
+ if (strlen (line))
+ add_pwd_line (line);
+
+ passwd_state.set_last_modified (pr.get_fhandle(), pr.get_fname ());
+ passwd_state = loaded;
+ pr.close ();
+ debug_printf ("Read /etc/passwd, %d lines", curr_lines);
+ }
+ else
+ {
+ static char linebuf[400];
+
+ debug_printf ("Emulating /etc/passwd");
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh",
+ cygheap->user.name (), (unsigned) DEFAULT_UID,
+ (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/");
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
+ }
+
+ }
return;
}
diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h
index 568259db2..d2dcfcd1a 100644
--- a/winsup/cygwin/pwdgrp.h
+++ b/winsup/cygwin/pwdgrp.h
@@ -44,12 +44,81 @@ public:
{
state = nstate;
}
- void set_last_modified (FILE *f)
+ void set_last_modified (HANDLE fh, const char *name)
{
if (!file_w32[0])
- strcpy (file_w32, cygheap->fdtab[fileno (f)]->get_win32_name ());
-
- GetFileTime (cygheap->fdtab[fileno (f)]->get_handle (),
- NULL, NULL, &last_modified);
+ strcpy (file_w32, name);
+ GetFileTime (fh, NULL, NULL, &last_modified);
}
};
+
+class pwdgrp_read {
+ path_conv pc;
+ HANDLE fh;
+ char *buf;
+ char *lptr, *eptr;
+
+public:
+ pwdgrp_read ()
+ : fh (INVALID_HANDLE_VALUE), buf (NULL), lptr (NULL), eptr (NULL) {}
+ virtual ~pwdgrp_read ()
+ {
+ close ();
+ if (buf)
+ free (buf);
+ }
+
+ bool open (const char *posix_fname)
+ {
+ if (buf)
+ free (buf);
+ buf = lptr = eptr = NULL;
+
+ pc.check (posix_fname);
+ if (pc.error || !pc.exists () || !pc.isdisk () || pc.isdir ())
+ return false;
+
+ fh = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ if (fh)
+ {
+ 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;
+ CloseHandle (fh);
+ fh = INVALID_HANDLE_VALUE;
+ 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
+ lptr = eptr;
+ eptr = strchr (lptr, '\n');
+ if (eptr)
+ *eptr++ = '\0';
+ return lptr;
+ }
+ inline HANDLE get_fhandle () { return fh; }
+ inline const char *get_fname () { return pc; }
+ void close ()
+ {
+ if (fh != INVALID_HANDLE_VALUE)
+ CloseHandle (fh);
+ fh = INVALID_HANDLE_VALUE;
+ }
+};