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;
}