URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 67193
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Как в программе на Си узнать от как..."

Отправлено auto_tips , 21-Май-10 10:32 
#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


Содержание

Сообщения в этом обсуждении
"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено Гений , 21-Май-10 10:32 
дооо, звать strcmp на стоку из двух байт....

"Как в программе на Си узнать от какого пользователя запущен ..."
Отправлено Anonimous , 21-Май-10 11:00 
>> strcmp на стоку из двух байт

А кто-то обещал, что всегда и везде будет именно "строка из двух байт"?
Ну тогда, во-первых, из трех. И, во-вторых, это решение будет работать с _любой_ строкой, в отличие от.
Ну и, в третьих, День Пионерии был позавчера. ;-)


"Как в программе на Си узнать от какого пользователя запущен ..."
Отправлено Одмин , 21-Май-10 12:04 
Какой вариант с твоей точки зрения правильный? Сравнить побайтно?

"Как в программе на Си узнать от какого пользователя запущен ..."
Отправлено pavlinux , 05-Июн-10 03:45 
Ниже смотри...

"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено vitja , 21-Май-10 13:13 
Чего-то не работает...

убрал 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


"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено FrBrGeorge , 24-Май-10 03:19 
Поправочка:

Эта программа показывает все акты регистрации пользователей, при которых в поле ut_line было записано ":0".

У меня не работает, во-первых, потому что в поле ut_line вообще никто не пишет ":0", а пишет в ut_host, во-вторых, потому что пишется ":0.0" (что единственно правильно для многоголовых карт), и в-третьих, потому что туда пишется запись при всяком открытии терминала, например, при запуске очередного xterm-а.


"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено cvsup , 24-Май-10 16:10 
Очередной день открытий.
Может, 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)


"На Bash/Awk"
Отправлено Igor , 24-Май-10 18:04 
Файл 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.


"Корректный вариант"
Отправлено Igor , 24-Май-10 19:36 
// 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


"Корректный вариант"
Отправлено pavlinux , 09-Июн-10 02:41 
>  if ( (entry->ut_host[0]==':') && (entry->ut_host[1]=='0') )

1. Если б я так написал с самого начала, вы б нифига не поняли о чем речь :)
   Оптимизация это хорошо, но при условии хорошей документации.

2. Хард-код это опасно, - entry->ut_host[1]=='0' не есть entry->ut_host[1] == 0;
Мелочь, а искать этот баг будешь ой как долго.



"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено cvsup , 24-Май-10 23:30 
Есть небольшой нюанс, ut_host - расширение стандарта POSIX.1. Иными словами, нельзя использовать ut_host в переносимом коде, это поле в стандарт не входит.

"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено Анонимко , 25-Май-10 13:03 
printf( "%s\n", getenv("LOGNAME") );

"Как в программе на Си узнать от какого пользователя запущен ..."
Отправлено Анонимко , 25-Май-10 13:04 
А понял, не о том речь. Пардоньте.

"Как в программе на Си узнать от какого пользователя запущен активный экран"
Отправлено pavlinux , 05-Июн-10 03:15 
Дополнение:

#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 и работает.


"Как в программе на Си узнать от какого пользователя запущен ..."
Отправлено Аноним , 05-Сен-15 21:33 
>pavlinux
>При запуске системы грузится демон, который чёй-то там делает...
>Как вы понимаете, демон грузится от рута

Ну да, с тобой всё понятно, какир.