📄 utmp.c
字号:
if (write(fd, (char *)u, sizeof(struct utmp)) != sizeof(struct utmp)) (void) ftruncate(fd, buf.st_size); } (void) close(fd);}#endif /* HAVE_UPDWTMP *//**************************************************************************** Update via utmp/wtmp (not utmpx/wtmpx).****************************************************************************/static void utmp_nox_update(struct utmp *u, BOOL claim){ pstring uname, wname;#if defined(PUTUTLINE_RETURNS_UTMP) struct utmp *urc;#endif /* PUTUTLINE_RETURNS_UTMP */ uw_pathname(uname, "utmp", ut_pathname); DEBUG(2,("utmp_nox_update: uname:%s\n", uname));#ifdef HAVE_PUTUTLINE if (strlen(uname) != 0) { utmpname(uname); }# if defined(PUTUTLINE_RETURNS_UTMP) setutent(); urc = pututline(u); endutent(); if (urc == NULL) { DEBUG(2,("utmp_nox_update: pututline() failed\n")); return; }# else /* PUTUTLINE_RETURNS_UTMP */ setutent(); pututline(u); endutent();# endif /* PUTUTLINE_RETURNS_UTMP */#else /* HAVE_PUTUTLINE */ if (strlen(uname) != 0) { pututline_my(uname, u, claim); }#endif /* HAVE_PUTUTLINE */ uw_pathname(wname, "wtmp", wt_pathname); DEBUG(2,("utmp_nox_update: wname:%s\n", wname)); if (strlen(wname) != 0) {#ifdef HAVE_UPDWTMP updwtmp(wname, u); /* * updwtmp() and the newer updwtmpx() may be unsymmetrical. * At least one OS, Solaris 2.x declares the former in the * "utmpx" (latter) file and context. * In the Solaris case this is irrelevant: it has both and * we always prefer the "x" case, so doesn't come here. * But are there other systems, with no "x", which lack * updwtmp() perhaps? */#else updwtmp_my(wname, u, claim);#endif /* HAVE_UPDWTMP */ }}/**************************************************************************** Copy a string in the utmp structure.****************************************************************************/static void utmp_strcpy(char *dest, const char *src, size_t n){ size_t len = 0; memset(dest, '\0', n); if (src) len = strlen(src); if (len >= n) { memcpy(dest, src, n); } else { if (len) memcpy(dest, src, len); }}/**************************************************************************** Update via utmpx/wtmpx (preferred) or via utmp/wtmp.****************************************************************************/static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim){#if !defined(HAVE_UTMPX_H) /* No utmpx stuff. Drop to non-x stuff */ utmp_nox_update(u, claim);#elif !defined(HAVE_PUTUTXLINE) /* Odd. Have utmpx.h but no "pututxline()". Drop to non-x stuff */ DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n")); utmp_nox_update(u, claim);#elif !defined(HAVE_GETUTMPX) /* Odd. Have utmpx.h but no "getutmpx()". Drop to non-x stuff */ DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n")); utmp_nox_update(u, claim);#else pstring uname, wname; struct utmpx ux, *uxrc; getutmpx(u, &ux);#if defined(HAVE_UX_UT_SYSLEN) if (hostname) ux.ut_syslen = strlen(hostname) + 1; /* include end NULL */ else ux.ut_syslen = 0;#endif#if defined(HAVE_UT_UT_HOST) utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));#endif uw_pathname(uname, "utmpx", ux_pathname); uw_pathname(wname, "wtmpx", wx_pathname); DEBUG(2,("utmp_update: uname:%s wname:%s\n", uname, wname)); /* * Check for either uname or wname being empty. * Some systems, such as Redhat 6, have a "utmpx.h" which doesn't * define default filenames. * Also, our local installation has not provided an override. * Drop to non-x method. (E.g. RH6 has good defaults in "utmp.h".) */ if ((strlen(uname) == 0) || (strlen(wname) == 0)) { utmp_nox_update(u, claim); } else { utmpxname(uname); setutxent(); uxrc = pututxline(&ux); endutxent(); if (uxrc == NULL) { DEBUG(2,("utmp_update: pututxline() failed\n")); return; } updwtmpx(wname, &ux); }#endif /* HAVE_UTMPX_H */}#if defined(HAVE_UT_UT_ID)/**************************************************************************** Encode the unique connection number into "ut_id".****************************************************************************/static int ut_id_encode(int i, char *fourbyte){ int nbase; const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; fourbyte[0] = 'S'; fourbyte[1] = 'M';/* * Encode remaining 2 bytes from 'i'. * 'ut_id_encstr' is the character set on which modulo arithmetic is done. * Example: digits would produce the base-10 numbers from '001'. */ nbase = strlen(ut_id_encstr); fourbyte[3] = ut_id_encstr[i % nbase]; i /= nbase; fourbyte[2] = ut_id_encstr[i % nbase]; i /= nbase; return(i); /* 0: good; else overflow */}#endif /* defined(HAVE_UT_UT_ID) *//* fill a system utmp structure given all the info we can gather */static BOOL sys_utmp_fill(struct utmp *u, const char *username, const char *hostname, struct in_addr *ipaddr, const char *id_str, int id_num){ struct timeval timeval; /* * ut_name, ut_user: * Several (all?) systems seems to define one as the other. * It is easier and clearer simply to let the following take its course, * rather than to try to detect and optimise. */#if defined(HAVE_UT_UT_USER) utmp_strcpy(u->ut_user, username, sizeof(u->ut_user));#elif defined(HAVE_UT_UT_NAME) utmp_strcpy(u->ut_name, username, sizeof(u->ut_name));#endif /* * ut_line: * If size limit proves troublesome, then perhaps use "ut_id_encode()". */ if (strlen(id_str) > sizeof(u->ut_line)) { DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n", id_str, (unsigned long)sizeof(u->ut_line))); return False; } utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));#if defined(HAVE_UT_UT_PID) u->ut_pid = sys_getpid();#endif/* * ut_time, ut_tv: * Some have one, some the other. Many have both, but defined (aliased). * It is easier and clearer simply to let the following take its course. * But note that we do the more precise ut_tv as the final assignment. */#if defined(HAVE_UT_UT_TIME) GetTimeOfDay(&timeval); u->ut_time = timeval.tv_sec;#elif defined(HAVE_UT_UT_TV) GetTimeOfDay(&timeval); u->ut_tv = timeval;#else#error "with-utmp must have UT_TIME or UT_TV"#endif#if defined(HAVE_UT_UT_HOST) utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));#endif#if defined(HAVE_UT_UT_ADDR) if (ipaddr) u->ut_addr = ipaddr->s_addr; /* * "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20. * Volunteer to implement, please ... */#endif#if defined(HAVE_UT_UT_ID) if (ut_id_encode(id_num, u->ut_id) != 0) { DEBUG(1,("utmp_fill: cannot encode id %d\n", id_num)); return False; }#endif return True;}/**************************************************************************** Close a connection.****************************************************************************/void sys_utmp_yield(const char *username, const char *hostname, struct in_addr *ipaddr, const char *id_str, int id_num){ struct utmp u; ZERO_STRUCT(u);#if defined(HAVE_UT_UT_EXIT) u.ut_exit.e_termination = 0; u.ut_exit.e_exit = 0;#endif#if defined(HAVE_UT_UT_TYPE) u.ut_type = DEAD_PROCESS;#endif if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return; sys_utmp_update(&u, NULL, False);}/**************************************************************************** Claim a entry in whatever utmp system the OS uses.****************************************************************************/void sys_utmp_claim(const char *username, const char *hostname, struct in_addr *ipaddr, const char *id_str, int id_num){ struct utmp u; ZERO_STRUCT(u);#if defined(HAVE_UT_UT_TYPE) u.ut_type = USER_PROCESS;#endif if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return; sys_utmp_update(&u, hostname, True);}#endif /* WITH_UTMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -