#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strcmp
#include <utmpx.h>#define XTTY ":0"
int main(void)
{
struct utmpx *entry;setutxent();
while ( (entry = getutxent()) != NULL) {
if ( !strcmp(entry->ut_line, XTTY) )
printf("%s %s\n",entry->ut_line, entry->ut_user);
}
endutxent();
return(EXIT_SUCCESS);
}URL:
Обсуждается: http://www.opennet.me/tips/info/2376.shtml
дооо, звать strcmp на стоку из двух байт....
>> strcmp на стоку из двух байтА кто-то обещал, что всегда и везде будет именно "строка из двух байт"?
Ну тогда, во-первых, из трех. И, во-вторых, это решение будет работать с _любой_ строкой, в отличие от.
Ну и, в третьих, День Пионерии был позавчера. ;-)
Какой вариант с твоей точки зрения правильный? Сравнить побайтно?
Ниже смотри...
Чего-то не работает...убрал strcmp
~ reboot
~ runlevel
tty4 LOGIN
tty5 LOGIN
tty2 LOGIN
tty3 LOGIN
tty6 LOGIN
tty1 LOGIN
tty7 myuser
pts/0 myuser
pts/2 myuser
pts/3 myuser
pts/5 myuser
pts/7 myuser
pts/8 myuser
pts/9 myuser
pts/10 myuser
pts/12 myuser
pts/14 myuser
pts/16 myuser
pts/18 myuser
pts/19 myuser
pts/1 myuser
Поправочка:Эта программа показывает все акты регистрации пользователей, при которых в поле ut_line было записано ":0".
У меня не работает, во-первых, потому что в поле ut_line вообще никто не пишет ":0", а пишет в ut_host, во-вторых, потому что пишется ":0.0" (что единственно правильно для многоголовых карт), и в-третьих, потому что туда пишется запись при всяком открытии терминала, например, при запуске очередного xterm-а.
Очередной день открытий.
Может, if ( !strcmp(entry->ut_host, XTTY) )
?ut_line The name of the TTY character device, without the leading /dev/
prefix, corresponding with the device used to facilitate the
user login session. If no TTY character device is used, this
field is left blank. This field is only applicable to entries
of type USER_PROCESS and LOGIN_PROCESS.ut_host The network hostname of the remote system, connecting to perform
a user login. If the user login session is not performed across
a network, this field is left blank. This field is only appli-
cable to entries of type USER_PROCESS.В линуксе afaik путевого мана нет.
В солярисе:
char ut_line[32]; /* device name (console, lnxx) */
char ut_host[257]; /* host name, if remote */Проверочное слово w, смотрим колонку FROM (ut_host)
Файл get_active_screen_user.sh:
#!/bin/bash
who | awk '{ if(match($5,":0")!=0) print $1 " " $2 }'Итог:
$ who
Результат:
igor tty2 2010-05-24 16:53
root tty3 2010-05-24 16:58
igor tty1 2010-05-24 15:14 (:0)
igor pts/2 2010-05-24 15:21 (:0.0)
igor pts/3 2010-05-24 15:46 (:0.0)$ ./get_active_screen_user.sh
Результат:
igor tty1
igor pts/2
igor pts/3
P.S.: OS Fedora 11.
// code getactivescreenuser.cpp
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
int main(void)
{
struct utmpx *entry;
setutxent();
while ( (entry = getutxent()) != NULL)
{
if ( (entry->ut_host[0]==':')&&(entry->ut_host[1]=='0') )
printf("%s %s\n",entry->ut_line, entry->ut_user);
}
endutxent();
return(EXIT_SUCCESS);
}Результат:
$ ./getactivescreenuser
tty1 igor
pts/2 igor
pts/3 igor
$ who
igor tty1 2010-05-24 15:14 (:0)
igor pts/2 2010-05-24 15:21 (:0.0)
igor pts/3 2010-05-24 17:55 (:0.0)
igor tty2 2010-05-24 18:35
> if ( (entry->ut_host[0]==':') && (entry->ut_host[1]=='0') )1. Если б я так написал с самого начала, вы б нифига не поняли о чем речь :)
Оптимизация это хорошо, но при условии хорошей документации.2. Хард-код это опасно, - entry->ut_host[1]=='0' не есть entry->ut_host[1] == 0;
Мелочь, а искать этот баг будешь ой как долго.
Есть небольшой нюанс, ut_host - расширение стандарта POSIX.1. Иными словами, нельзя использовать ut_host в переносимом коде, это поле в стандарт не входит.
printf( "%s\n", getenv("LOGNAME") );
А понял, не о том речь. Пардоньте.
Дополнение:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strcmp
#include <utmpx.h>#define XTTY ":0"
int main(void)
{
struct utmpx *entry;setutxent();
while ((entry = getutxent()) != NULL) {
if (!strcmp(entry->ut_line, XTTY) && (entry->ut_type == USER_PROCESS))printf("%s %s\n", entry->ut_line, entry->ut_user);
}
endutxent();
return(EXIT_SUCCESS);
}Бережем наносекунды! - strcmpless version
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strcmp
#include <utmpx.h>int main(void)
{
const char *XTTY = ":0";
struct utmpx *entry;
short i = 0;setutxent();
while ((entry = getutxent()) != NULL) {
if (entry->ut_type == USER_PROCESS) {
while (*XTTY && *entry->ut_line) {
if (*XTTY++ != entry->ut_line[i++])
break;
}
if (*XTTY || entry->ut_line[i]) continue;printf("%s %s\n", entry->ut_line, entry->ut_user);
}
}
endutxent();
return(EXIT_SUCCESS);
}
/* Кто переделает без переменной i, тому с полки пирожок :) */
Тайный смысл в этих извращениях был такой:При запуске системы грузится демон, который чёй-то там делает...
По сигналу свыше, этот демон должен снять дамп экрана Х-ов, если они есть и,
отослать вызывающему.
Как вы понимаете, демон грузится от рута, переменные окружения свои, так что,
ни какой речи о getenv, не может и быть. Вызывать who и парсить результаты вывода -
это через ж..пу и для web-программеров, они всё подряд парсят.Собственно, если запустите strace -e open who, то увидите, что он именно так, через utmp и работает.
>pavlinux
>При запуске системы грузится демон, который чёй-то там делает...
>Как вы понимаете, демон грузится от рутаНу да, с тобой всё понятно, какир.