diff options
author | Roland McGrath <roland@gnu.org> | 1996-05-29 04:48:04 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-05-29 04:48:04 +0000 |
commit | 0200214b288810fc261b0b65c32f7068fcfa9b40 (patch) | |
tree | a488a0a435ccf62b0870121b839b08de0d37a9b5 /login/pututline_r.c | |
parent | 215dbbb1508bd6b86211112dd5ddaf9bd2290690 (diff) | |
download | glibc-0200214b288810fc261b0b65c32f7068fcfa9b40.tar glibc-0200214b288810fc261b0b65c32f7068fcfa9b40.tar.gz glibc-0200214b288810fc261b0b65c32f7068fcfa9b40.tar.bz2 glibc-0200214b288810fc261b0b65c32f7068fcfa9b40.zip |
Tue May 28 04:38:10 1996 Ulrich Drepper <drepper@cygnus.com>
* limits.h: Change MB_LEN_MAX to 6. A 31-bit ISO 10646
character in UTF-8 encoding has that many bytes.
* locale/langinfo.h: New element _NL_CTYPE_MB_CUR_MAX.
* locale/categories.def: Add description of field _NL_CTYPE_MB_CUR_MAX.
* locale/Makefile (routines): Add mb_cur_max.
* locale/mb_cur_max.c: New file. This function gets called
when the macro MB_CUR_MAX is used.
* locale/C-ctype.c: Initialize new mb_cur_max field.
* locale/localeinfo.h: Change magic value because of incompatible
change.
* locale/programs/ld-ctype.c: Determine value of mb_cur_max
according to current character set and write it out with the rest.
* stdlib/stdlib.h (MB_CUR_MAX): Not constant anymore. Get value
according to currently used locale for catefory LC_CTYPE by
calling the function __ctype_get_mb_cur_max.
Tue May 28 03:27:46 1996 Ulrich Drepper <drepper@cygnus.com>
* FAQ: Fix some typos.
Tell that for Linux the kernel header files are necessary.
* PROJECTS: New file. List of open jobs for glibc.
* Makefile (distribute): Add PROJECTS.
* crypt/GNUmakefile (headers): New variable. Mention crypt.h.
* crypt/crypt.h: Header for crypt functions.
* elf/elf.h: Add some new constants from recent Cygnus ELF
header files.
* login/getutid_r.c: Test for correct type.
Don't depend on ut_type and ut_id unless _HAVE_UT_TYPE and
_HAVE_UT_ID resp. are defined.
Make really compliant with specification.
* login/getutline_r.c, login/pututline_r.c: Don't depend on
ut_type and ut_id unless _HAVE_UT_TYPE and _HAVE_UT_ID resp. are
defined.
Make really compliant with specification.
* login/setutent_r.c: Don't depend on ut_type and ut_id unless
_HAVE_UT_TYPE and _HAVE_UT_ID resp. are defined.
* login/login.c, login/logout.c, login/logwtmp.c: Complete
rewrite. Now based on getut*/setut* functions.
* stdlib/strtol.c: Undo changes of Wed May 22 01:48:54 1996.
This prevented using this file in other GNU packages.
* sysdeps/gnu/utmpbits.h: Define _HAVE_UT_TYPE, _HAVE_UT_ID,
and _HAVE_UT_TV because struct utmp has these members.
* sysdeps/libm-i387/e_exp.S: Correct exp(+-Inf) case.
* utmp.h: New file. Wrapper around login/utmp.h.
* elf/dl-error.c (struct catch): New type.
(catch): New static variable, struct catch *.
(catch_env, signalled_errstring, signalled_objname): Variables removed.
(_dl_signal_error): If CATCH is non-null, set its errstring and
objname members and jump to CATCH->env. If it is null, call
_dl_sysdep_fatal with a standard message.
* elf/rtld.c (dl_main): Explode `doit' function into dl_main's body.
No longer use _dl_catch_error.
Diffstat (limited to 'login/pututline_r.c')
-rw-r--r-- | login/pututline_r.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/login/pututline_r.c b/login/pututline_r.c index 92ba8fb308..07322e5740 100644 --- a/login/pututline_r.c +++ b/login/pututline_r.c @@ -26,9 +26,29 @@ Boston, MA 02111-1307, USA. */ #include <sys/file.h> +/* XXX An alternative solution would be to call a SUID root program + which write the new value. */ + int pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data) { + struct stat st; + int result = 0; + +#if _HAVE_UT_TYPE - 0 + /* Test whether ID has any of the legal types because we have to + prevent illegal entries. */ + if (id->ut_type != RUN_LVL && id->ut_type != BOOT_TIME + && id->ut_type != OLD_TIME && id->ut_type != NEW_TIME + && id->ut_type != INIT_PROCESS && id->ut_type != LOGIN_PROCESS + && id->ut_type != USER_PROCESS && id->ut_type != DEAD_PROCESS) + /* No, using '<' and '>' for the test is not possible. */ + { + errno = EINVAL; + return -1; + } +#endif + /* Open utmp file if not already done. */ if (utmp_data->ut_fd == -1) { @@ -37,12 +57,14 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data) return -1; } +#if _HAVE_UT_TYPE - 0 /* Seek position to write. */ if (utmp_data->ubuf.ut_type != utmp_ptr->ut_type) { /* We must not overwrite the data in UTMP_DATA. */ struct utmp_data *data_tmp = alloca (sizeof (utmp_data)); struct utmp *dummy; + off_t new_pos; *data_tmp = *utmp_data; utmp_data = data_tmp; @@ -50,23 +72,25 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data) if (getutid_r (utmp_ptr, &dummy, utmp_data) < 0) { if (errno != ESRCH) + /* Some error occured. If no entry was found, the position + pointer now is at the end of the file. */ return -1; - utmp_data->loc_utmp = lseek (utmp_data->ut_fd, 0, SEEK_END); - if (utmp_data->loc_utmp == -1) - return -1; - } + /* Set position pointer to position after adding of the record. */ + utmp_data->loc_utmp += sizeof (struct utmp); } +#endif + + /* Find out how large the file is. */ + if (fstat (utmp_data->ut_fd, &st) < 0) + return -1; /* Position file correctly. */ - if (utmp_data->loc_utmp > 0 + if (utmp_data->loc_utmp <= st.st_size && lseek (utmp_data->ut_fd, utmp_data->loc_utmp - sizeof (struct utmp), SEEK_SET) < 0) return -1; - /* XXX An alternative solution would be to call an SUID root program - which write the new value. */ - /* Try to lock the file. */ if (flock (utmp_data->ut_fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS) { @@ -78,12 +102,22 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data) } /* Write the new data. */ - if (write (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp)) + if (write (utmp_data->ut_fd, utmp_ptr, sizeof (struct utmp)) != sizeof (struct utmp)) - return -1; + { + /* If we appended a new record this is only partially written. + Remove it. */ + if (utmp_data->loc_utmp > st.st_size) + { + (void) ftruncate (utmp_data->ut_fd, st.st_size); + utmp_data->loc_utmp = st.st_size; + } + + result = -1; + } /* And unlock the file. */ (void) flock (utmp_data->ut_fd, LOCK_UN); - return 0; + return result; } |