[C] read utmp/wtmp file FreeBSD

Programovacie jazyky, rady, poradňa...
c-ice
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 475
Registrovaný: 04 mar 2008, 15:18
Kontaktovať používateľa:

[C] read utmp/wtmp file FreeBSD

Príspevok od používateľa c-ice »

Nechcem od nikoho vypracovat zadanie len či to už niekto robil a či viete poradit nejaký postup funkciu ktoru by som mohol použit prípadne nejaké návrhy ...
pôvodny plán bol že to bude nejak strukturovane ukladané a ja to budem parsovat ale neje tomu tak aspon z pohladu textoveho mozno binarne...
vsetko to bezi na freeBSD staršia verzia takže <utmp.h> nemá žiadne funkcie su tam iba definovane struktury
další nápad je pomocou známych príkazov WHO,W,FINGER,LAST ktoré z týmito subormi narábaju vytvorit tmp subor vypisu a ten parsovat ale to sa mi nezdá že môžem takto riešit ...
ešte ak niekto máte zdorjové kódy týchto prikazov v C dost by mi to pomohlo (viem že open source na nete ale nenašiel som to)

Kód: Vybrať všetko

/*
 * Meno: 
 * Kruzok: 
 * Datum:  
 * Zadanie: zadanie_4_09
 * Kompilacia: gcc zadanie_4_09.c -o zadanie_4_09
 *
 * Text zadania:
 * Napiste program, ktory vypise informacie o prihlasenom pouzivatelovi, ktory je argumentom programu.  
 * Ak je pouzivatel prihlaseny program zobrazi cas jeho prihlasenia ak nie je zobrazi cas jeho posledneho 
 * odhlasenia.
 * 
 *  
 * Syntax:
 * zadanie_4_09 [-h] <user>
 *  
 * Poznamka: Na zistenie info pouzite subory /var/run/utmp a /var/log/wtmp (vid man utmp).
 *
 *
 * Program musi osetrovat pocet a spravnost argumentov. Program musi mat help,
 * ktory sa vypise pri zadani argumentu -h a ma tvar:
 * Meno programu (C) meno autora
 *  
 * Usage: <meno_programu> <arg1> <arg2> ...
 *    <arg1>: xxxxxx
 *    <arg2>: yyyyy
 *  
 * Korektny vystup programu musi ist na standardny vystup (stdout).
 * Chybovy vystup programu musi ist na chybovy vystup (stderr).
 * Chybovy vystup musi mat tvar:
 * Error: 'adresar, subor, program,... pri ktorom nastala chyba': popis chyby ...
 * Ak program pouziva nejake pomocne vypisy, musia ist na chybovy vystup a 
 * musia mat tvar:
 * Debug: vypis ...
 *  
 * Program sa musi dat skompilovat !!!
 * Prikaz pre kompilaciu je uvedeny vyssie, v pripade potreby ho modifikujte !!!
 *
 * Poznamky: (sem vlozte pripadne poznamky k vypracovanemu zadaniu)
 * 
 * Riesenie:
 */
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Určite pozeráš správny utmp.h súbor? V glibc sú dva, v bits/utmp.h sú len tie štruktúry, ale v tom druhom sú aj funkcie.
c-ice
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 475
Registrovaný: 04 mar 2008, 15:18
Kontaktovať používateľa:

Príspevok od používateľa c-ice »

chrono napísal:Určite pozeráš správny utmp.h súbor? V glibc sú dva, v bits/utmp.h sú len tie štruktúry, ale v tom druhom sú aj funkcie.
JJ pozeral dobrý ako vravím mame v skole stary FreeBSD tam ešte nepodporuje tieto funkcie takže tak ale konečne som na to prišiel ked som si prečital čo som sem napisal tak mi to napadlo ja som vôbec nepozrel HEX editorom ako vyzera utmp resp. wtmp s "bitoveho" pohladu lenivy som bol si niečo ako PSPad nainštalovat na ubuntu :( teraz pozeram že to ma presne taku strukturu aka je deklarovana v utmp.h takže môžem veselo parsovat po bytoch a už som vyriešil aj načitanie a prevod "time_t" na čas
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Aká verzia glibc tam je (lebo tie funkcie sú v glibc dosť dlho)? Nechce sa mi to hľadať presne, ale tie funkcie boli už aj v libc 2.1 a tá verzia je z roku 1999.
c-ice
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 475
Registrovaný: 04 mar 2008, 15:18
Kontaktovať používateľa:

Príspevok od používateľa c-ice »

chrono napísal:Aká verzia glibc tam je (lebo tie funkcie sú v glibc dosť dlho)? Nechce sa mi to hľadať presne, ale tie funkcie boli už aj v libc 2.1 a tá verzia je z roku 1999.
je tam verzia z 1994 :)
//EDIT 9.12.2009
tak zadanie odoslane :) aby sa nepovedalo pridam sem hotovy zdrojak pre dalšie generacie :roll:

Kód: Vybrať všetko

/*

 * Meno: c-ice

 * Kruzok: os-2

 * Datum: 9.12.2009

 * Zadanie: zadanie_4_09

 * Kompilacia: gcc zadanie_4_09.c -o zadanie_4_09

 *

 * Text zadania:

 * Napiste program, ktory vypise informacie o prihlasenom pouzivatelovi, ktory je argumentom programu.  

 * Ak je pouzivatel prihlaseny program zobrazi cas jeho prihlasenia ak nie je zobrazi cas jeho posledneho 

 * odhlasenia.

 * 

 *  

 * Syntax:

 * ./zadanie_4_09 [-h] [-p <user>]

 *  

 * Poznamka: Na zistenie info pouzite subory /var/run/utmp a /var/log/wtmp (vid man utmp).

 *

 *

 * Program musi osetrovat pocet a spravnost argumentov. Program musi mat help,

 * ktory sa vypise pri zadani argumentu -h a ma tvar:

 * Meno programu (C) meno autora

 *  

 * Usage: <meno_programu> <arg1> <arg2> ...

 *    <arg1>: xxxxxx

 *    <arg2>: yyyyy

 *  

 * Korektny vystup programu musi ist na standardny vystup (stdout).

 * Chybovy vystup programu musi ist na chybovy vystup (stderr).

 * Chybovy vystup musi mat tvar:

 * Error: 'adresar, subor, program,... pri ktorom nastala chyba': popis chyby ...

 * Ak program pouziva nejake pomocne vypisy, musia ist na chybovy vystup a 

 * musia mat tvar:

 * Debug: vypis ...

 *  

 * Program sa musi dat skompilovat !!!

 * Prikaz pre kompilaciu je uvedeny vyssie, v pripade potreby ho modifikujte !!!

 *

 * Poznamky: (sem vlozte pripadne poznamky k vypracovanemu zadaniu)

 * I like C/C++ :)

 * 

 * Riesenie:

 */

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <utmp.h>

#include <time.h>

#include <string.h>

 

void Help();

struct utmp GetUtmpByName(int iSubor,char *sMeno);



FILE *fTmp;



int main(int argc, char *argv[]) {

	int o;

	char user[16];

	static struct utmp gLast;

	int i;

	opterr = 0;

// tu zacina taky cyklus ktory bol ako template z ulohov

	while ((o = getopt(argc, argv, "hp:")) != -1)

		switch (o) {

			case 'h':

				Help();

				exit (0);

			case 'p':

				//printf("OUTPUT: '%s': parameter prepinaca -p\npocet argumentov=%i\n", optarg,argc);

//optind statment z funkcie getopt je tam ulozene cislo nasledujuceho argumentu

				i=optind-1; 

/* 

 * zacina cyklus ktory je tu kvoli tomu ze za parametrom -p sa môže uviest viacej uzivatelskych mien

 * tuto vymozenost nemam tak priamo popisanu v zadani ale po prekonzultovani som ju sem umiestnil 

 * zistuje to na zaklade poctu argumentov do kedy sa ma nacitavat...

 */

				do{

//do premennej user ulozim argument cize udajne uzivatelske meno

					sprintf(user,"%s",argv[i]);

//volam funckiu pisanu dole

					gLast=GetUtmpByName(0,user);

					if (strcmp(gLast.ut_name,user)!=0) {

						gLast=GetUtmpByName(1,user);

						if (strcmp(gLast.ut_name,user)!=0) {

							fprintf(stderr, "Error: Uzivatel %s Pravdepodobne neexistuje \n",user);

							//exit(1);

						}else {

							printf("OUTPUT: %s bol naposledy prihlaseny: ",user);

							printf("%s",ctime(&gLast.ut_time));

							}

					}else {

						printf("OUTPUT: %s je prave prihlaseny od: ",user);

						printf("%s",ctime(&gLast.ut_time));

						}

					//fprintf(stderr,"DEBUG: terminal=%s\n",gLast.ut_line);

					//fprintf(stderr,"DEBUG: meno=%s\n",gLast.ut_name);

					//fprintf(stderr,"DEBUG: host=%s\n",gLast.ut_host);

					i++;

				}while(i<argc);

				exit (0);

				break;

			case '?':

			default:

				fprintf(stderr, "Error: '%c': nespravny prepinac\n", optopt);

				exit(1);

		}

	argc -= optind;

	argv += optind;

}

// Funkcia Help zavolam ju ked treba vypisat help :D

void Help() {

/* Sem treba dopisat help */ //tu som dopisal help 

	printf("zadanie_4_09 (C) [email protected]\n");

	printf(	"musis zadat za program parameter -p "uzivatelske meno"\n"

			"uzivatela u ktorého chceš zistit ci je prihlaseny alebo kedy sa odhlasil resp. uzivatelov\n"

			"napr. ./zadanie_4_09 -p user1 user2 user3 fogel user4 09056431 ...\n");

}



/* ******************************************************************************* 

 * CopyRight [email protected] *

 * ***********************

 * Funkcia GetUtmpByName(...)

 * Vracia structuru typu UTMP v ktorej sa nachadzaju udaje o poslednom výskyte, 

 * hladaneho mena ,ktore je vstupným argumentom funkcie. 

 * Funkcia prehladáva jeden zo súborov bud utmp alebo wtmp toto sa určí vstupným

 * argumentom iSubor cize 0 => utmp , 1 => wtmp

 * cestu ku suborom beriem z makra definovaneho v "utmp.h"

 * Pre spravne otvorenie suborov zistujem velkost pomocou funckie fstat

 * a nasledne ju testujem ak je menej resp rovne nule program sa ukonci z 

 * chybovou hláškou, dalej idem do cyklu v ktorom po Bytoch!!! nacitavam znaky

 * ked pridem na znak "t" zacnem nacitavat do gUtmp co je staticka premenna

 * struktura utmp testujem snej prvok ut_name a ak sa zhoduje zo zadanym menom

 * tak celu premenu ulozim do gLast ktoru po prebehnuti cyklu vraciam pomocou

 * return.

 * ******************************************************************************/



struct utmp GetUtmpByName(int iSubor,char *sMeno){

	struct stat file_stats;

	static struct utmp gUtmp,gLast;

	size_t size;

	int i=0,pom,znak;

	if(iSubor==0)

		fTmp=fopen(_PATH_UTMP,"rb");

	else

		fTmp=fopen(_PATH_WTMP,"rb");

	fstat(fileno(fTmp), &file_stats);

	size = file_stats.st_size;

	if (size <= 0) {

		fclose(fTmp);

		fprintf(stderr, "Error: zo suboru sa neda citat \n");

		exit(1);

	}

	for(i=0;i<size;i++) {

		znak=getc(fTmp);

		if(znak=='t'){

			ungetc(znak,fTmp);

			for (pom=0;pom<UT_LINESIZE;pom++)gUtmp.ut_line[pom]=getc(fTmp);

			for (pom=0;pom<UT_NAMESIZE;pom++)gUtmp.ut_name[pom]=getc(fTmp);

			for (pom=0;pom<UT_HOSTSIZE;pom++)gUtmp.ut_host[pom]=getc(fTmp);

			gUtmp.ut_time=getw(fTmp);

			i+=UT_LINESIZE+UT_NAMESIZE+UT_HOSTSIZE+4;

			//i+=16+16+8+4;

			//fprintf(stderr,"DEBUG: terminal=%s\n",gUtmp.ut_line);

			//fprintf(stderr,"DEBUG: meno=%s\n",gUtmp.ut_name);

			//fprintf(stderr,"DEBUG: host=%s\n",gUtmp.ut_host);

			//fprintf(stderr,"DEBUG: cas=%s\n",ctime(&gUtmp.ut_time));

			if (strcmp(gUtmp.ut_name,sMeno)==0)gLast=gUtmp;

		}

	}	

	fclose(fTmp);

	return gLast;

}
Napísať odpoveď