ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/logging.C
(Generate patch)

Comparing rxvt-unicode/src/logging.C (file contents):
Revision 1.7 by pcg, Fri Feb 13 12:16:21 2004 UTC vs.
Revision 1.18 by root, Tue Nov 8 17:35:28 2005 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * File: logging.c 2 * File: logging.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 1992 John Bovey <jdb@ukc.ac.uk> 6 * Copyright (c) 1992 John Bovey <jdb@ukc.ac.uk>
7 * - original version 7 * - original version
12 * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es> 12 * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es>
13 * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> 13 * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com>
14 * - extensive modifications 14 * - extensive modifications
15 * Copyright (c) 1999 D J Hawkey Jr <hawkeyd@visi.com> 15 * Copyright (c) 1999 D J Hawkey Jr <hawkeyd@visi.com>
16 * - lastlog support 16 * - lastlog support
17 * Copyright (c) 2004 Marc Lehmann <pcg@goof.com>
17 * 18 *
18 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or 21 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version. 22 * (at your option) any later version.
41#include "../config.h" /* NECESSARY */ 42#include "../config.h" /* NECESSARY */
42#include "rxvt.h" /* NECESSARY */ 43#include "rxvt.h" /* NECESSARY */
43#include "logging.h" 44#include "logging.h"
44#ifdef UTMP_SUPPORT 45#ifdef UTMP_SUPPORT
45 46
47#if HAVE_STRUCT_UTMP
48int rxvt_write_bsd_utmp (int utmp_pos, struct utmp *wu);
49void rxvt_update_wtmp (const char *fname, const struct utmp *putmp);
50#endif
51
52void rxvt_update_lastlog (const char *fname, const char *pty, const char *host);
53
46/* 54/*
47 * BSD style utmp entry 55 * BSD style utmp entry
48 * ut_line, ut_name, ut_host, ut_time 56 * ut_line, ut_name, ut_host, ut_time
49 * SYSV style utmp (and utmpx) entry 57 * SYSV style utmp (and utmpx) entry
50 * ut_user, ut_id, ut_line, ut_pid, ut_type, ut_exit, ut_time 58 * ut_user, ut_id, ut_line, ut_pid, ut_type, ut_exit, ut_time
57 */ 65 */
58void 66void
59rxvt_term::makeutent (const char *pty, const char *hostname) 67rxvt_term::makeutent (const char *pty, const char *hostname)
60{ 68{
61#ifdef HAVE_STRUCT_UTMP 69#ifdef HAVE_STRUCT_UTMP
62 struct utmp *ut = & (this->ut); 70 struct utmp *ut = &this->ut;
63#endif 71#endif
64#ifdef HAVE_STRUCT_UTMPX 72#ifdef HAVE_STRUCT_UTMPX
65 struct utmpx *utx = & (this->utx); 73 struct utmpx *utx = &this->utx;
66#endif 74#endif
67#ifdef HAVE_UTMP_PID 75#ifdef HAVE_UTMP_PID
68 int i; 76 int i;
69#endif 77#endif
70 char ut_id[5];
71 struct passwd *pwent = getpwuid (getuid ()); 78 struct passwd *pwent = getpwuid (getuid ());
72 79
73 if (!STRNCMP (pty, "/dev/", 5)) 80 if (!strncmp (pty, "/dev/", 5))
74 pty += 5; /* skip /dev/ prefix */ 81 pty += 5; /* skip /dev/ prefix */
75 82
76 if (!STRNCMP (pty, "pty", 3) || !STRNCMP (pty, "tty", 3))
77 {
78 STRNCPY (ut_id, (pty + 3), sizeof (ut_id));
79 }
80#ifdef HAVE_UTMP_PID 83#ifdef HAVE_UTMP_PID
84 if (!strncmp (pty, "pty", 3) || !strncmp (pty, "tty", 3))
85 strncpy (ut_id, pty + 3, sizeof (ut_id));
81 else if (sscanf (pty, "pts/%d", &i) == 1) 86 else if (sscanf (pty, "pts/%d", &i) == 1)
82 sprintf (ut_id, "vt%02x", (i & 0xff)); /* sysv naming */ 87 sprintf (ut_id, "vt%02x", (i & 0xff)); /* sysv naming */
83#endif
84 else if (STRNCMP (pty, "pty", 3) && STRNCMP (pty, "tty", 3)) 88 else if (strncmp (pty, "pty", 3) && strncmp (pty, "tty", 3))
85 { 89 {
86 rxvt_print_error ("can't parse tty name \"%s\"", pty); 90 rxvt_warn ("can't parse tty name \"%s\", not adding utmp entry.\n", pty);
87 return; 91 return;
88 } 92 }
93#endif
89 94
90#ifdef HAVE_STRUCT_UTMP 95#ifdef HAVE_STRUCT_UTMP
91 MEMSET (ut, 0, sizeof (struct utmp)); 96 memset (ut, 0, sizeof (struct utmp));
92# ifdef HAVE_UTMP_PID 97# ifdef HAVE_UTMP_PID
93 setutent (); 98 setutent ();
94 STRNCPY (ut->ut_id, ut_id, sizeof (ut->ut_id)); 99 strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
95 ut->ut_type = DEAD_PROCESS; 100 ut->ut_type = DEAD_PROCESS;
96 getutid (ut); /* position to entry in utmp file */ 101 getutid (ut); /* position to entry in utmp file */
97 STRNCPY (ut_id, ut_id, sizeof (ut_id)); 102 strncpy (ut_id, ut_id, sizeof (ut_id));
98# endif
99#endif 103# endif
104#endif
100 105
101#ifdef HAVE_STRUCT_UTMPX 106#ifdef HAVE_STRUCT_UTMPX
102 MEMSET (utx, 0, sizeof (struct utmpx)); 107 memset (utx, 0, sizeof (struct utmpx));
103 setutxent (); 108 setutxent ();
104 STRNCPY (utx->ut_id, ut_id, sizeof (utx->ut_id)); 109 strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
105 utx->ut_type = DEAD_PROCESS; 110 utx->ut_type = DEAD_PROCESS;
106 getutxid (utx); /* position to entry in utmp file */ 111 getutxid (utx); /* position to entry in utmp file */
107 STRNCPY (ut_id, ut_id, sizeof (ut_id)); 112 strncpy (ut_id, ut_id, sizeof (ut_id));
108#endif 113#endif
109 114
110#ifdef HAVE_STRUCT_UTMP 115#ifdef HAVE_STRUCT_UTMP
111 STRNCPY (ut->ut_line, pty, sizeof (ut->ut_line)); 116 strncpy (ut->ut_line, pty, sizeof (ut->ut_line));
112 ut->ut_time = time (NULL); 117 ut->ut_time = time (NULL);
113# ifdef HAVE_UTMP_PID 118# ifdef HAVE_UTMP_PID
114 STRNCPY (ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", 119 strncpy (ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
115 sizeof (ut->ut_user)); 120 sizeof (ut->ut_user));
116 STRNCPY (ut->ut_id, ut_id, sizeof (ut->ut_id)); 121 strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
117 ut->ut_time = time (NULL); 122 ut->ut_time = time (NULL);
118 ut->ut_pid = cmd_pid; 123 ut->ut_pid = cmd_pid;
119# ifdef HAVE_UTMP_HOST 124# ifdef HAVE_UTMP_HOST
120 STRNCPY (ut->ut_host, hostname, sizeof (ut->ut_host)); 125 strncpy (ut->ut_host, hostname, sizeof (ut->ut_host));
121# endif 126# endif
122 ut->ut_type = USER_PROCESS; 127 ut->ut_type = USER_PROCESS;
123 pututline (ut); 128 pututline (ut);
124 endutent (); /* close the file */ 129 endutent (); /* close the file */
125 utmp_pos = 0; 130 utmp_pos = 0;
126# else 131# else
127 STRNCPY (ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?", 132 strncpy (ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
128 sizeof (ut->ut_name)); 133 sizeof (ut->ut_name));
129# ifdef HAVE_UTMP_HOST 134# ifdef HAVE_UTMP_HOST
130 STRNCPY (ut->ut_host, hostname, sizeof (ut->ut_host)); 135 strncpy (ut->ut_host, hostname, sizeof (ut->ut_host));
131# endif
132# endif 136# endif
133#endif 137# endif
138#endif
134 139
135#ifdef HAVE_STRUCT_UTMPX 140#ifdef HAVE_STRUCT_UTMPX
136 STRNCPY (utx->ut_line, pty, sizeof (utx->ut_line)); 141 strncpy (utx->ut_line, pty, sizeof (utx->ut_line));
137 STRNCPY (utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", 142 strncpy (utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
138 sizeof (utx->ut_user)); 143 sizeof (utx->ut_user));
139 STRNCPY (utx->ut_id, ut_id, sizeof (utx->ut_id)); 144 strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
145# if HAVE_UTMPX_SESSION
140 utx->ut_session = getsid (0); 146 utx->ut_session = getsid (0);
147# endif
141 utx->ut_tv.tv_sec = time (NULL); 148 utx->ut_tv.tv_sec = time (NULL);
142 utx->ut_tv.tv_usec = 0; 149 utx->ut_tv.tv_usec = 0;
143 utx->ut_pid = cmd_pid; 150 utx->ut_pid = cmd_pid;
144# ifdef HAVE_UTMPX_HOST 151# ifdef HAVE_UTMPX_HOST
145 STRNCPY (utx->ut_host, hostname, sizeof (utx->ut_host)); 152 strncpy (utx->ut_host, hostname, sizeof (utx->ut_host));
146# if 0 153# if 0
147 { 154 {
148 char *colon; 155 char *colon;
149 156
150 if ((colon = STRRCHR (ut->ut_host, ':')) != NULL) 157 if ((colon = strrchr (ut->ut_host, ':')) != NULL)
151 *colon = '\0'; 158 *colon = '\0';
152 } 159 }
153# endif 160# endif
154# endif 161# endif
155 utx->ut_type = USER_PROCESS; 162 utx->ut_type = USER_PROCESS;
169# else 176# else
170 FILE *fd0; 177 FILE *fd0;
171 178
172 if ((fd0 = fopen (TTYTAB_FILENAME, "r")) != NULL) 179 if ((fd0 = fopen (TTYTAB_FILENAME, "r")) != NULL)
173 { 180 {
174 char buf[256], name[256]; 181 char buf[256], name[256];
175 182
176 buf[sizeof (buf) - 1] = '\0'; 183 buf[sizeof (buf) - 1] = '\0';
177 for (i = 1; (fgets (buf, sizeof (buf) - 1, fd0) != NULL);) 184 for (i = 1; (fgets (buf, sizeof (buf) - 1, fd0) != NULL);)
178 { 185 {
179 if (*buf == '#' || sscanf (buf, "%s", name) != 1) 186 if (*buf == '#' || sscanf (buf, "%s", name) != 1)
180 continue; 187 continue;
181 if (!STRCMP (ut->ut_line, name)) 188 if (!strcmp (ut->ut_line, name))
182 { 189 {
183 if (!rxvt_write_bsd_utmp (i, ut)) 190 if (!rxvt_write_bsd_utmp (i, ut))
184 i = 0; 191 i = 0;
185 utmp_pos = i; 192 utmp_pos = i;
186 fclose (fd0); 193 fclose (fd0);
195 } 202 }
196#endif 203#endif
197 204
198#ifdef WTMP_SUPPORT 205#ifdef WTMP_SUPPORT
199# ifdef WTMP_ONLY_ON_LOGIN 206# ifdef WTMP_ONLY_ON_LOGIN
200 if (Options & Opt_loginShell) 207 if (options & Opt_loginShell)
201# endif 208# endif
202 { 209 {
203# ifdef HAVE_STRUCT_UTMP 210# ifdef HAVE_STRUCT_UTMP
204# ifdef HAVE_UPDWTMP 211# ifdef HAVE_UPDWTMP
205 updwtmp (RXVT_WTMP_FILE, ut); 212 updwtmp (RXVT_WTMP_FILE, ut);
206# else 213# else
207 rxvt_update_wtmp (RXVT_WTMP_FILE, ut); 214 rxvt_update_wtmp (RXVT_WTMP_FILE, ut);
208# endif 215# endif
209# endif 216# endif
210# ifdef HAVE_STRUCT_UTMPX 217# ifdef HAVE_STRUCT_UTMPX
218# if HAVE_UPDWTMPX
211 updwtmpx (RXVT_WTMPX_FILE, utx); 219 updwtmpx (RXVT_WTMPX_FILE, utx);
220# else
221 pututxline (utx);
222# endif
212# endif 223# endif
213 } 224 }
214#endif 225#endif
215#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE) 226#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE)
216 if (Options & Opt_loginShell) 227 if (options & Opt_loginShell)
217 rxvt_update_lastlog (RXVT_LASTLOG_FILE, pty, hostname); 228 rxvt_update_lastlog (RXVT_LASTLOG_FILE, pty, hostname);
218#endif 229#endif
219} 230}
220 231
221/* ------------------------------------------------------------------------- */ 232/* ------------------------------------------------------------------------- */
224 */ 235 */
225void 236void
226rxvt_term::cleanutent () 237rxvt_term::cleanutent ()
227{ 238{
228#ifdef HAVE_STRUCT_UTMP 239#ifdef HAVE_STRUCT_UTMP
229 struct utmp *ut = & (this->ut); 240 struct utmp *ut = &this->ut;
230#endif 241#endif
231#ifdef HAVE_STRUCT_UTMPX 242#ifdef HAVE_STRUCT_UTMPX
232 struct utmpx *tmputx, *utx = & (this->utx); 243 struct utmpx *tmputx, *utx = &this->utx;
233#endif 244#endif
234 245
235#ifdef HAVE_STRUCT_UTMP 246#ifdef HAVE_STRUCT_UTMP
236# ifdef HAVE_UTMP_PID 247# ifdef HAVE_UTMP_PID
237 MEMSET (ut, 0, sizeof (struct utmp)); 248 memset (ut, 0, sizeof (struct utmp));
238 setutent (); 249 setutent ();
239 STRNCPY (ut->ut_id, ut_id, sizeof (ut->ut_id)); 250 strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
240 ut->ut_type = USER_PROCESS; 251 ut->ut_type = USER_PROCESS;
241 { 252 {
242 struct utmp *tmput = getutid (ut); 253 struct utmp *tmput = getutid (ut);
243 254
244 if (tmput) /* position to entry in utmp file */ 255 if (tmput) /* position to entry in utmp file */
245 ut = tmput; 256 ut = tmput;
246 } 257 }
247 ut->ut_type = DEAD_PROCESS; 258 ut->ut_type = DEAD_PROCESS;
248# else 259# else
249 MEMSET (ut->ut_name, 0, sizeof (ut->ut_name)); 260 memset (ut->ut_name, 0, sizeof (ut->ut_name));
250# ifdef HAVE_UTMP_HOST 261# ifdef HAVE_UTMP_HOST
251 MEMSET (ut->ut_host, 0, sizeof (ut->ut_host)); 262 memset (ut->ut_host, 0, sizeof (ut->ut_host));
252# endif 263# endif
253# endif 264# endif
254 ut->ut_time = time (NULL); 265 ut->ut_time = time (NULL);
255#endif 266#endif
256 267
257#ifdef HAVE_STRUCT_UTMPX 268#ifdef HAVE_STRUCT_UTMPX
258 MEMSET (utx, 0, sizeof (struct utmpx)); 269 memset (utx, 0, sizeof (struct utmpx));
259 setutxent (); 270 setutxent ();
260 STRNCPY (utx->ut_id, ut_id, sizeof (utx->ut_id)); 271 strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
261 utx->ut_type = USER_PROCESS; 272 utx->ut_type = USER_PROCESS;
262 if ((tmputx = getutxid (utx))) /* position to entry in utmp file */ 273 if ((tmputx = getutxid (utx))) /* position to entry in utmp file */
263 utx = tmputx; 274 utx = tmputx;
264 utx->ut_type = DEAD_PROCESS; 275 utx->ut_type = DEAD_PROCESS;
276# if HAVE_UTMPX_SESSION
265 utx->ut_session = getsid (0); 277 utx->ut_session = getsid (0);
278# endif
266 utx->ut_tv.tv_sec = time (NULL); 279 utx->ut_tv.tv_sec = time (NULL);
267 utx->ut_tv.tv_usec = 0; 280 utx->ut_tv.tv_usec = 0;
268#endif 281#endif
269 282
270 /* 283 /*
271 * Write ending wtmp entry 284 * Write ending wtmp entry
272 */ 285 */
273#ifdef WTMP_SUPPORT 286#ifdef WTMP_SUPPORT
274# ifdef WTMP_ONLY_ON_LOGIN 287# ifdef WTMP_ONLY_ON_LOGIN
275 if (Options & Opt_loginShell) 288 if (options & Opt_loginShell)
276# endif 289# endif
277 { 290 {
278# ifdef HAVE_STRUCT_UTMP 291# ifdef HAVE_STRUCT_UTMP
279# ifdef HAVE_UPDWTMP 292# ifdef HAVE_UPDWTMP
280 updwtmp (RXVT_WTMP_FILE, ut); 293 updwtmp (RXVT_WTMP_FILE, ut);
281# else 294# else
282 rxvt_update_wtmp (RXVT_WTMP_FILE, ut); 295 rxvt_update_wtmp (RXVT_WTMP_FILE, ut);
283# endif 296# endif
284# endif 297# endif
285# ifdef HAVE_STRUCT_UTMPX 298# ifdef HAVE_STRUCT_UTMPX
299# if HAVE_UPDWTMPX
286 updwtmpx (RXVT_WTMPX_FILE, utx); 300 updwtmpx (RXVT_WTMPX_FILE, utx);
301# else
302 pututxline (utx);
303# endif
287# endif 304# endif
288 } 305 }
289#endif 306#endif
290 307
291 /* 308 /*
295# ifdef HAVE_UTMP_PID 312# ifdef HAVE_UTMP_PID
296 if (ut->ut_pid == cmd_pid) 313 if (ut->ut_pid == cmd_pid)
297 pututline (ut); 314 pututline (ut);
298 endutent (); 315 endutent ();
299# else 316# else
300 MEMSET (ut, 0, sizeof (struct utmp)); 317 memset (ut, 0, sizeof (struct utmp));
301 rxvt_write_bsd_utmp (utmp_pos, ut); 318 rxvt_write_bsd_utmp (utmp_pos, ut);
302# endif 319# endif
303#endif 320#endif
304#ifdef HAVE_STRUCT_UTMPX 321#ifdef HAVE_STRUCT_UTMPX
305 if (utx->ut_pid == cmd_pid) 322 if (utx->ut_pid == cmd_pid)
311/* ------------------------------------------------------------------------- */ 328/* ------------------------------------------------------------------------- */
312/* 329/*
313 * Write a BSD style utmp entry 330 * Write a BSD style utmp entry
314 */ 331 */
315#ifdef HAVE_UTMP_H 332#ifdef HAVE_UTMP_H
316/* INTPROTO */
317int 333int
318rxvt_write_bsd_utmp (int utmp_pos, struct utmp *wu) 334rxvt_write_bsd_utmp (int utmp_pos, struct utmp *wu)
319{ 335{
320 int fd; 336 int fd;
321 337
331 347
332/* ------------------------------------------------------------------------- */ 348/* ------------------------------------------------------------------------- */
333/* 349/*
334 * Update a BSD style wtmp entry 350 * Update a BSD style wtmp entry
335 */ 351 */
336#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP) 352#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP) && defined(HAVE_STRUCT_UTMP)
337/* INTPROTO */
338void 353void
339rxvt_update_wtmp (const char *fname, const struct utmp *putmp) 354rxvt_update_wtmp (const char *fname, const struct utmp *putmp)
340{ 355{
341 int fd, gotlock, retry; 356 int fd, gotlock, retry;
342 struct flock lck; /* fcntl locking scheme */ 357 struct flock lck; /* fcntl locking scheme */
374} 389}
375#endif 390#endif
376 391
377/* ------------------------------------------------------------------------- */ 392/* ------------------------------------------------------------------------- */
378#ifdef LASTLOG_SUPPORT 393#ifdef LASTLOG_SUPPORT
379/* INTPROTO */
380void 394void
381rxvt_update_lastlog (const char *fname, const char *pty, const char *host) 395rxvt_update_lastlog (const char *fname, const char *pty, const char *host)
382{ 396{
383# ifdef HAVE_STRUCT_LASTLOGX 397# ifdef HAVE_STRUCT_LASTLOGX
384 struct lastlogx llx; 398 struct lastlogx llx;
391# endif 405# endif
392 struct passwd *pwent; 406 struct passwd *pwent;
393# endif 407# endif
394 408
395# ifdef HAVE_STRUCT_LASTLOGX 409# ifdef HAVE_STRUCT_LASTLOGX
396 MEMSET (&llx, 0, sizeof (llx)); 410 memset (&llx, 0, sizeof (llx));
397 llx.ll_tv.tv_sec = time (NULL); 411 llx.ll_tv.tv_sec = time (NULL);
398 llx.ll_tv.tv_usec = 0; 412 llx.ll_tv.tv_usec = 0;
399 STRNCPY (llx.ll_line, pty, sizeof (llx.ll_line)); 413 strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
400 STRNCPY (llx.ll_host, host, sizeof (llx.ll_host)); 414 strncpy (llx.ll_host, host, sizeof (llx.ll_host));
401 updlastlogx (RXVT_LASTLOGX_FILE, getuid (), &llx); 415 updlastlogx (RXVT_LASTLOGX_FILE, getuid (), &llx);
402# endif 416# endif
403 417
404# ifdef HAVE_STRUCT_LASTLOG 418# ifdef HAVE_STRUCT_LASTLOG
405 pwent = getpwuid (getuid ()); 419 pwent = getpwuid (getuid ());
406 if (!pwent) 420 if (!pwent)
407 { 421 {
408 rxvt_print_error ("no entry in password file"); 422 rxvt_warn ("no entry in password file, not updating lastlog.\n");
409 return; 423 return;
410 } 424 }
425
411 MEMSET (&ll, 0, sizeof (ll)); 426 memset (&ll, 0, sizeof (ll));
412 ll.ll_time = time (NULL); 427 ll.ll_time = time (NULL);
413 STRNCPY (ll.ll_line, pty, sizeof (ll.ll_line)); 428 strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
414 STRNCPY (ll.ll_host, host, sizeof (ll.ll_host)); 429 strncpy (ll.ll_host, host, sizeof (ll.ll_host));
415# ifdef LASTLOG_IS_DIR 430# ifdef LASTLOG_IS_DIR
416 sprintf (lastlogfile, "%.*s/%.*s", 431 sprintf (lastlogfile, "%.*s/%.*s",
417 sizeof (lastlogfile) - sizeof (pwent->pw_name) - 2, fname, 432 sizeof (lastlogfile) - sizeof (pwent->pw_name) - 2, fname,
418 sizeof (pwent->pw_name), 433 sizeof (pwent->pw_name),
419 (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown" 434 (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown"

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines