2012-07-13 51 views
2

我想捕獲通過我的程序中的GUI登錄的用戶名。我的程序作爲root登錄的守護進程運行。如果非root用戶通過GUI登錄,我的程序應該被通知。 我粘貼我的當前程序,調用perl腳本,利用系統調用來檢查當前登錄的用戶是誰。我也粘貼了我的perl腳本以供參考。如何檢測在Linux中通過GUI登錄的用戶

#include <X11/Xlib.h> 
#include <X11/Xos.h> 
#include <X11/Xfuncs.h> 
#include <X11/Xutil.h> 
#include <X11/Xatom.h> 
int main() 
{ 
    char *user; 
    char buf[1024]; 
    int fd, ret; 
    fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT); 
    if (!fd) { 
     printf("Error opening file\n"); 
     exit(1); 
    } 
    chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP 
      | S_IROTH | S_IWOTH | S_IXOTH); 
    daemon(0, 0); 
    while (1) { 
     system("perl /home/curr-usr.pl"); 
     sleep(5); 
    } 
    return 0; 
} 

這是用來獲取登錄的當前用戶的perl腳本。

#!/usr/bin/perl 
my $result; 
$result = `whoami`; 
open FH, "+>>", "/tmp/log" or die $!; 
print FH "$result "; 
close (FH); 

在C程序上面,我是調用perl腳本在while循環每5秒。 perl腳本使用命令「whoami」來獲取當前登錄的用戶&將其轉儲到/ tmp/log文件中。

我想實現的是,如果user1登錄perl腳本,應該讓我當前用戶爲user1。相反,perl腳本給我root作爲當前用戶,而不管我通過GUI登錄的用戶,因爲我使用root用戶運行C程序的perl腳本&。

任何人都可以請我提供一種機制,通過它C程序可以知道當前用戶通過GUI登錄? 任何幫助,不勝感激。

+0

我不知道從X11子系統你想提取登錄信息...爲什麼不使用電子郵件。 G。一些用於檢測用戶登錄的Linux API? – 2012-07-13 09:03:17

+0

我真正想要的是有X Window&用戶當前登錄的映射。我們如何使用Linux API檢測用戶登錄,當我們在一個用戶中持續運行程序時,我的要求是讓所有用戶登錄在我開始執行程序後到系統。謝謝 – user1439609 2012-07-13 09:37:18

回答

1

正如你所提到的,你的程序作爲一個守護進程運行。因此,它產生的任何進程都將作爲啓動守護進程的用戶運行。通過用戶界面(或任何其他方法)登錄的用戶從不是您可以通過從守護程序中調用whoami獲得的用戶。

相反,你應該做的是顯式地通知你的守護進程一個登錄事件,或者,如果這不是一個選項,保留當前在該框上運行的所有登錄會話的列表,並查看是否出現新會話 - 將會是新登錄用戶的會話。

0

程序whousers從文件/var/run/utmp獲取他們的信息。

該文件包含N個大小爲「struct utmp」的條目,在<utmp.h>中定義 您對USER_PROCESS類型條目感興趣。主機字段包含顯示。

請注意,如果用戶打開某些終端仿真(xterm,konsole ...),則同一顯示會有多個條目。

您可以監視此文件或/var/log/wtmp的歷史

struct utmp ut_entry; 
FILE *fp = fopen(UTMP_FILE, "r"); 

if(!fp) 
{ 
    printf("Could not open utmp file!"); 
    return; 
} 

while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1) 
{ 
    if(ut_entry.ut_type != USER_PROCESS) 
     continue; 

    // string entries are not 0 terminated if too long... 
    // copy user name to make sure it is 0 terminated 

    char tmpUser[UT_NAMESIZE+1] = {0}; 
    strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE); 

    // do more stuff... read the display from ut_entry.host 
} 

欲瞭解更多信息,請參閱我使用XFCE4和LXDM的utmp manual page

+0

在某些情況下,登錄管理器可能不會保持最新的'utmp'記錄。我在Ubuntu 11.04上的XFCE4上看到了這個例子。如果這是一個問題,user1439609可能不得不將問題更改爲「*檢測在本機上活動的所有用戶*」;只需掃描'/ proc/PID /'目錄(使用'opendir()','readdir()','stat()')來查看哪些用戶帳戶正在運行進程並忽略系統(已知的非人類)用戶。 – 2012-10-02 18:54:55

1

。 「誰」和「用戶」僅報告登錄終端的用戶。作爲名義動物指出,GUI登錄未被報告(謝謝!)。我使用「pgrep xfce」來檢查XFCE4是否正在運行。繼打印出當前XFCE用戶:

#!/usr/bin/perl 

# Get all processes 
my @xfce_processes = `pgrep xfce`; 

# If processes exist, get user of first process in list. 
if(scalar @xfce_processes) { 
    print `ps -o user h $xfce_processes[0]`; 
} 
else 
{ 
# No xfce processes. 
    ; 
} 
+0

如果有多個XFCE會話正在進行,該怎麼辦?例如,如果人們使用「切換用戶」來允許多個gui登錄。我將如何獲得當前用戶?這涉及到我這樣的問題在這裏:http://stackoverflow.com/questions/17996707/how-do-i-get-the-username-owning-the-currently-active-gui-session – oligofren 2013-08-02 08:08:21

0

你可能想調查或者ConsoleKit或其更新的化身loginctl

這些工具是專門爲管理座椅和會議設計,同時保持本地文本控制檯,GUI和遠程會話之間的區別。他們是而不是保證在每臺X11機器上都有,但是如果你的機器是相對較新的,它很有可能會使用其中一種或其他工具。

+0

太糟糕loginctl使用systemd這在發行版中不太廣泛使用。否則,它看起來好像它是一個非常適合我的問題http://stackoverflow.com/questions/17996707/how-do-i-get-the-username-owning-the-currently-active-gui-session – oligofren 2013-08-05 14:27:51

1

可以使用主顯示這樣的檢測用戶:

#!/bin/bash 

#Detect the name of the display in use 
display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)" 

#Detect the user using such display 
user=$(who | grep '('$display')' | awk '{print $1}') 

#Detect the id of the user 
uid=$(id -u $user) 
相關問題