نوشته شده به وسیلهی: Mohsen در 1 سال 4 ماه پیش تحت عنوان کدهای-متفرقه پیاده-سازی-برنامه-های-لینوکس
دستور lastlog(8) در سیستمهای شبه یونیکس زمان آخرین لاگین کاربر در سیستم را نشان میدهد. این اطلاعات در فایلی به نام lastlog و به صورت struct در آفست خاصی از آن ذخیره شده است. به عنوان مثال اطلاعات کاربری با USERID=1000
در آفست زیر قرار دارد:
off_t offset = 1000 * sizeof(struct lastlog);
حال کافی است فایل را باز کرده، به آفست مورد نظر رفته و اطلاعات فایل را بخوانیم. برای لینک کردن USERID با نام واقعی باید از توابع مربوط به فایل /etc/passwd
استفاده کنیم.
کد این برنامه را ملاحظه میکنید:
/*
* lastlog(8) simulation
*
* Mohsen Safari
* ----------------------------------
*
* dokaj.ir
* safari.tafreshi@gmail.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <lastlog.h>
#include <err.h>
#include <pwd.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <paths.h>
#include <time.h>
#include <string.h>
void
usage(const char *program_name)
{
fprintf(stderr, "usage: %s [-h -u login-name]\n", program_name);
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
struct passwd *passwd;
struct lastlog lastlog;
ssize_t num_read;
int fd, flag = 0, opt;
time_t time;
struct tm *tm;
char buf[40];
char *user = NULL;
while ((opt = getopt(argc, argv, ":hu:")) != -1) {
switch (opt) {
case 'u':
user = optarg;
break;
case 'h':
usage(argv[0]);
//NOTREACHED
case '?':
errx(EXIT_FAILURE, "unknown option -%c", optopt);
case ':':
errx(EXIT_FAILURE, "-%c needs argument", optopt);
}
}
fd = open(_PATH_LASTLOG, O_RDONLY);
if (fd == -1)
err(EXIT_FAILURE, "open");
setpwent();
memset(&lastlog, 0, sizeof(struct lastlog));
do {
errno = 0;
passwd = user ? getpwnam(user) : getpwent();
if (passwd == NULL) {
if (errno)
err(EXIT_FAILURE, "getpw*");
if (user)
errx(EXIT_FAILURE, "Unknown user: %s", user);
// EOF
break;
}
if (lseek(fd, passwd->pw_uid * sizeof(struct lastlog), SEEK_SET) == -1)
err(EXIT_FAILURE, "lseek");
if ((num_read = read(fd, &lastlog, sizeof(lastlog))) == -1)
err(EXIT_FAILURE, "read");
time = lastlog.ll_time;
if (time == 0)
strcpy(buf, "**Never logged in**");
else {
tm = localtime(&time);
strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %z %Y", tm);
}
if (!flag) {
printf("Username Port From Latest\n");
flag = 1;
}
printf("%-16s %-8s %-16s %-s\n", passwd->pw_name, lastlog.ll_line,
lastlog.ll_host, buf);
} while (user == NULL);
endpwent();
close(fd);
exit(EXIT_SUCCESS);
}
کامپایل برنامه و نمونه خروجی آن به صورت زیر است:
$ gcc -o lastlog lastlog.c
$ ./lastlog | tail -8
mohsen tty1 Wed Dec 23 23:51:44 +0330 2020
systemd-coredump **Never logged in**
mysql **Never logged in**
debian-tor **Never logged in**
lightdm **Never logged in**
tcpdump **Never logged in**
fake tty3 Wed Dec 23 21:22:59 +0330 2020
sara **Never logged in**
$ ./lastlog -u fake
Username Port From Latest
fake tty3 Wed Dec 23 21:22:59 +0330 2020
من محسن هستم؛ برنامهنویس PHP و Laravel و Zend Framework و پایتون و فلسک، ولی بیشتر تمرکزم روی لاراول است. این سایت را اولین بار با فلسک نوشتم ولی بعد تصمیم گرفتم آن را با لاراول نیز پیادهسازی کنم. هم نسخهی فسلک و هم نسخهی لاراول را میتوانید روی گیتهابم پیدا و دانلود کنید.
برای ارتباط با من یا در همین سایت کامنت بگذارید و یا به dokaj.ir(at)gmail.com ایمیل بزنید.
در مورد این مطلب یادداشتی بنویسید.