zugriffsrechte einer datei mit einem programm (C++) ausgeben

N

Naphaneal

unregistriert
Thread Starter
Dabei seit
05.12.2007
Beiträge
4.085
Reaktionspunkte
343
hi!

ich hab ein kleines problem mit folgender aufgabe:

Erstellen Sie ein kleines C/C++ Programm, daß die Zugriffsrechte einer Datei ausgibt.


folgenden code hab ich bereits geschrieben, aber das ergebnis ist immer 0

Code:
#include <iostream>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
using namespace std;


main()
{
        char zeichenkette[256];         // variable zur ausgabe des dateiinhalts
        struct stat AbfrageZugriffsrechte;
        ifstream FileEingabe ("/Users/naphaneal/fh_uebungen/BS_uebung/junktext.txt"); //einlesen des inhalts der datei
       
		cout << "Ausgabe zugriffsrechte der Datei junktext.txt" << endl;
        		cout << "------------------------------------------------" << endl;
       		
		 FileEingabe.getline(zeichenkette, 256); //schreibe inhalt der datei nach zeichenkette mit max. laenge 256 zeichen
        		
		cout << "Inhalt der Datei: " << zeichenkette << endl; //ausgabe des inhalts
       		cout << "Datei hat folgende Zugriffsrechte: " <<AbfrageZugriffsrechte.st_mode << endl; //beabsichtigte ausgabe der zugriffsrechte

}


ich weiß, daß die zugriffsrechte über st_mode (siehe man 2 stat) gehandhabt werden können.


wie kann ich die entsprechenden modi so auslesen, daß sie eine verständliche information liefern? und was sagt mir die 0 bei der ausgabe?

greez

Naph
 
Zuletzt bearbeitet:
1) Ich sehe überhaupt nicht, wie Du
Code:
AbfrageZugriffsrechte
überhaupt setzt
2) Zur Verständlichen ausgabe gebe ich mal den Tip: Beschäftige Dich mal mit Octalzahlen.

Noch mehr Hausaufgabenhilfe ist wirklich nicht drin.

Alex
 
mist...da is die formatierung flöten gegangen...

das is nen
Code:
struct stat AbfrageZugriffsrechte

das zugriffsrechte in UNIX auch mit oktalzahlen vergeben und ausgedrückt werden können, weiß ich. aber is das hier eine oktalzahl? ich hatte den eindruck, daß es sich vielmehr um eine dezimalzahl handelt.

btw: is keine hausaufgabe...die übung verlangt lediglich die zugriffsrechte per ls und chmod zu ermitteln.
 
Aber Du musst die struct stat auch füllen, das passiert ja nicht durch zauberei!

man 2 stat ist ja schon die richtige Stelle.

Und Zugriffsrechte lassen sich am besten Oktal prüfen.... den Code hab ich hier, aber ich denke, soviel Motivation hast Du jetzt doch ;)

Alex
 
sorry, aber ich kann dir nicht folgen...

aber mal was anderes...beim durchlesen von man 2 stat is mir folgendes aufgefallen.

in der struct stat steht bei st_mode /*inode protection mode*/

und bei struct stat64 /*mode of file*/

weil benutze ich diese structure krieg ich nen wert >0 raus

hab ich evtl. das falsche struct stat benutzt?
 
Ja, stat64 ist auch richtig. st_mode ist der inode protection mode

Alex
 
frage...kann es sein, daß in st_mode die anzahl der auf das file gesetzten flags steht?
 
Nein. Aber auf der Manpage ist das auch genauer erklärt.
Ansonsten, wie Alex schon sagte -- mit den Oktalzahlen und minimalen Nachdenken kriegt man's denke ich auch ohne weitere Doku hin, wenn man st_mode hat.
 
also ich hab den code mal etwas abgeändert.

Code:
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <fcntl.h>
using namespace std;


main()
{
char zeichenkette[256]; //variable zur ausgabe des dateiinhalts
int returnvalue;
struct stat buffer;
ifstream FileEingabe ("/Users/naphaneal/fh_uebungen/BS_uebung/junktext.txt"); //einlesen des inhalts der datei
cout << "Ausgabe zugriffsrechte der Datei junktext.txt" << endl;
cout << "------------------------------------------------" << endl;

FileEingabe.getline(zeichenkette, 256); //schreibe inhalt der datei nach zeichenkette mit max. laenge 256 zeichen

cout << "Inhalt der Datei: " << zeichenkette << endl; //ausgabe des inhalts
returnvalue = stat("/Users/naphaneal/fh_uebungen/BS_uebung/junktext.txt", &buffer);

cout << "Rueckgabewert des Funktionsaufrufs: " << returnvalue << endl;
cout << "device inode resides on: " << buffer.st_dev << endl;
cout << "inode's number: " << buffer.st_ino << endl;

cout << "inode protection mode: " << buffer.st_mode << endl;
cout << "number or hard links to the file: " << buffer.st_nlink << endl;
cout << "user ID of owner: " << buffer.st_uid << endl;

cout << "group ID of owner: " << buffer.st_gid << endl;
cout << "device type: " << buffer.st_rdev << endl;
cout << "file size: " << buffer.st_size << endl;

cout << "blocks: " << buffer.st_blocks << endl;
cout << "blocksize: " << buffer.st_blksize << endl;
cout << "flags: " << buffer.st_flags << endl;
cout << "file generation number: " << buffer.st_gen << endl;
}

die ausgabe auf dem bildschirm:

Code:
Ausgabe zugriffsrechte der Datei junktext.txt
------------------------------------------------
Inhalt der Datei: hier steht irgendwas drin
Rueckgabewert des Funktionsaufrufs: 0
device inode resides on: 234881026
inode's number: 25889156
inode protection mode: 33252
number or hard links to the file: 1
user ID of owner: 501
group ID of owner: 20
device type: 0
file size: 26
blocks: 8
blocksize: 4096
flags: 0
file generation number: 0

anscheinend war die ausgegebene 0 der rückgabewert der aufgerufenen funktion. und der is bei erfolg 0

während ich nun beim aufruf buffer.st_mode die zahl 33252 erhalte.

ich verstehe die zahl jetzt so:

andere dürfen auf die datei schreiben
gruppe darf schreiben und ausführen
user darf auf die datei schreiben

ich bezweifle aber, daß die interpretation stimmt...vor allem, weil die datei folgende zugriffsrechte gesetzt hat:

-rwxr--r-- (oder oktal 744)

wie erklärt sich die 33252 nun?
 
Zuletzt bearbeitet:
Ich habe leider von dem Thema gar keine Ahnung, finde aber, dass du dir wirklich Mühe gibst und dir jetzt ruhig jemand weiterhelfen kann. :)
Los, Ihr Programmierer, habt Euch nicht so.
 
Die 33252 liegt daran, dass das Feld noch mehr Infos enthält (z.B. setuid bit, ob's ein Symlink ist, etc), die man mit bitwise and abfragen kann. Um mal die Manpage zu zitieren:
Code:
The status information word st_mode has the following bits:

     #define S_IFMT 0170000           /* type of file */
     #define        S_IFIFO  0010000  /* named pipe (fifo) */
     #define        S_IFCHR  0020000  /* character special */
     #define        S_IFDIR  0040000  /* directory */
     #define        S_IFBLK  0060000  /* block special */
     #define        S_IFREG  0100000  /* regular */
     #define        S_IFLNK  0120000  /* symbolic link */
     #define        S_IFSOCK 0140000  /* socket */
     #define        S_IFWHT  0160000  /* whiteout */
     #define S_ISUID 0004000  /* set user id on execution */
     #define S_ISGID 0002000  /* set group id on execution */
     #define S_ISVTX 0001000  /* save swapped text even after use */
     #define S_IRUSR 0000400  /* read permission, owner */
     #define S_IWUSR 0000200  /* write permission, owner */
     #define S_IXUSR 0000100  /* execute/search permission, owner */

=> st_mode & S_IRUSR != 0 (aka User kann lesen)
=> st_mode & 0200 != 0 (aka User kann schreiben)
=> st_mode & 0040 != 0 (aka Gruppe kann lesen)
=> st_mode & 0001 == 0 (aka world kann nicht ausführen)

etc


Oder alternativ kann man die "überflüssigen" Infos rausfiltern: 33252 & 0777 == 0744
 
ich hab da was übersehen, denke ich.

ist das nicht so, daß cout den wert in protection mode dezimal ausgibt? weil dann müsste ich die als oktal ausgeben lassen, oder nicht?
 
Korrekt. Wie man das macht, weiß ich allerdings nicht, von C++ hab ich nicht so viel Ahnung. Wenn du's mit printf (C) oder NSLog (Objective-C) machen wolltest, müsstest du als Formatcode %o benutzen.
 
yo...hab's mit printf gemacht...die formatierung mit cout zu machen is ja übel... :sick:

btw:

Code:
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <fcntl.h>
using namespace std;


main()
{
char dateiinhalt[256];                                                                  //variable zur ausgabe des dateiinhalts
char pathorfilename[256]; //variable zum einlesen des pfad- bzw. dateinamens
int returnvalue, zahl;
struct stat buffer;

cout << "Geben Sie eine Datei (mit Pfad) oder den Pfad an: " << endl;
cin >> pathorfilename;

ifstream FileEingabe (pathorfilename); //einlesen des inhalts der datei
cout << "Ausgabe Zugriffsrechte einer Datei" << endl;   
cout << "------------------------------------------------" << endl;    FileEingabe.getline(dateiinhalt,256); //schreibe inhalt der datei nach dateiinhalt mit max. laenge 256 zeichen 
cout << "Inhalt der Datei: " << dateiinhalt << endl;  //ausgabe des inhalts
returnvalue = stat(pathorfilename, &buffer);
cout << "Rueckgabewert des Funktionsaufrufs: " << returnvalue << endl;
cout << "device inode resides on: " << buffer.st_dev << endl;
cout << "inode's number: " << buffer.st_ino << endl;
cout << "inode protection mode: " << buffer.st_mode << endl;
cout << "number or hard links to the file: " << buffer.st_nlink << endl;
cout << "user ID of owner: " << buffer.st_uid << endl;
cout << "group ID of owner: " << buffer.st_gid << endl;
cout << "device type: " << buffer.st_rdev << endl;
cout << "file size: " << buffer.st_size << endl;
cout << "blocks: " << buffer.st_blocks << endl;
cout << "blocksize: " << buffer.st_blksize << endl;
cout << "flags: " << buffer.st_flags << endl;
cout << "file generation number: " << buffer.st_gen << endl;
zahl = buffer.st_mode;
printf("inode protection mode in octal: %o\n", zahl);
}

ergibt z.B.:

Code:
Geben Sie eine Datei (mit Pfad) oder den Pfad an: 
/Users/
Ausgabe Zugriffsrechte einer Datei
------------------------------------------------
Inhalt der Datei: 
Rueckgabewert des Funktionsaufrufs: 0
device inode resides on: 234881026
inode's number: 31112
inode protection mode: 16877
number or hard links to the file: 5
user ID of owner: 0
group ID of owner: 80
device type: 0
file size: 170
blocks: 0
blocksize: 4096
flags: 0
file generation number: 0
inode protection mode in octal: 40755

jetzt muß ich das programm nur noch so erweitern, daß ein verständlicherer text erzeugt wird.

also sowas wie 100744 wird zu "folgende rechte hat die datei"

aber nicht mehr heute...

@below

kannste deinen code mal zum vergleich posten?
 
Zuletzt bearbeitet:
so...hab den code nun soweit fertig, daß er die gewünschten ergebnisse anzeigt.

http://rafb.net/p/tFTYob52.html

jetzt geht's im grunde nur noch um die kosmetik...

wie könnte man den code etwas besser gestalten?

btw. wer will kann den code mal auf seinem rechner ausprobieren.

die ausgabe zum aktuellen code sieht wie folgt aus:

Code:
Geben Sie eine Datei (mit Pfad) oder den Pfad an: 
/Users
Ausgabe Zugriffsrechte einer Datei
------------------------------------------------
Rueckgabewert des Funktionsaufrufs: 0
Inhalt der Datei: 
device inode resides on: 234881026
inode's number: 31112
inode protection mode: 16877
number or hard links to the file: 5
user ID of owner: 0
group ID of owner: 80
device type: 0
file size: 170
blocks: 0
blocksize: 4096
flags: 0
file generation number: 0
inode protection mode in octal: 40755
Dateirechte nach folgender Reihenfolge directory owner group others
drwxr-xr-x
 
Zuletzt bearbeitet:
hallo naphaneal,
könntest du vllt deinen src-code nochmal posten? bei deinem link kommt leider nur ein weißer bildschirm :(
würde mich aber sehr für deine umwandlung von octal zu drwxr-xr-x etc interessieren :)
 
äh....muß ich suchen...

edit: is nich schön. aber für die übung hat's damals gereicht...sollte auch nur dazu dienen sich mit dem dateisystem zu beschäftigen.
blöderweise wird die formatierung nicht überall beibehalten. hoffe man kann's trotzdem lesen.
Code:
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <fcntl.h>
using namespace std;

main()
{
	char dateiinhalt[256];								[COLOR="lime"]//variable zur ausgabe des dateiinhalts[/COLOR]
	char pathorfilename[256];							[COLOR="lime"]//variable zum einlesen des pfad- bzw. dateinamens[/COLOR]
	int returnvalue, oktalwertrechte, other, group, owner, regular, directory;	
	struct stat buffer;

	cout << [COLOR="red"]"Geben Sie eine Datei (mit Pfad) oder den Pfad an: "[/COLOR] << endl;
	cin >> pathorfilename;
	
	ifstream FileEingabe (pathorfilename);				         [COLOR="lime"]//einlesen des verzeichnis- bzw. dateinamens/-pfades[/COLOR]
	cout << [COLOR="red"]"Ausgabe Zugriffsrechte einer Datei"[/COLOR] << endl;			
	cout << [COLOR="red"]"------------------------------------------------"[/COLOR] << endl;			
	FileEingabe.getline(dateiinhalt,256);					 [COLOR="lime"]//schreibe inhalt der ersten zeile in  datei nach dateiinhalt mit max. laenge 256 zeichen[/COLOR]
	returnvalue = stat(pathorfilename, &buffer);		         [COLOR="lime"]//setze returnvalue auf rueckgabewert der funktion stat. rueckgabewert 0, wenn datei gefunden[/COLOR]
	if (returnvalue == 0)
	{
		cout << [COLOR="red"]"Rueckgabewert des Funktionsaufrufs: "[/COLOR] << returnvalue << endl;
		cout << [COLOR="red"]"Inhalt der Datei: "[/COLOR] << dateiinhalt << endl;		                      [COLOR="lime"]//ausgabe der 1. zeile des dateiinhalts[/COLOR]
		cout << [COLOR="red"]"device inode resides on: "[/COLOR] << buffer.st_dev << endl;
		cout << [COLOR="red"]"inode's number: "[/COLOR] << buffer.st_ino << endl;
		cout << [COLOR="red"]"inode protection mode: "[/COLOR] << buffer.st_mode << endl;
		cout << [COLOR="red"]"number or hard links to the file: "[/COLOR] << buffer.st_nlink << endl;
		cout << [COLOR="red"]"user ID of owner: "[/COLOR] << buffer.st_uid << endl;
		cout << [COLOR="red"]"group ID of owner: "[/COLOR] << buffer.st_gid << endl;
		cout << [COLOR="red"]"device type: "[/COLOR] << buffer.st_rdev << endl;
		cout << [COLOR="red"]"file size: "[/COLOR] << buffer.st_size << endl;
		cout << [COLOR="red"]"blocks: "[/COLOR] << buffer.st_blocks << endl;
		cout << [COLOR="red"]"blocksize: "[/COLOR] << buffer.st_blksize << endl;
		cout << [COLOR="red"]"flags: "[/COLOR] << buffer.st_flags << endl;
		cout << [COLOR="red"]"file generation number: "[/COLOR] << buffer.st_gen << endl;
		oktalwertrechte = buffer.st_mode;	
		other = oktalwertrechte%8;								      [COLOR="lime"]//ermittle oktalwert für other[/COLOR]
		group = (oktalwertrechte/8)%8;							              [COLOR="lime"]//ermittle oktalwert fuer group[/COLOR]
		owner = ((oktalwertrechte/8)/8)%8;						              [COLOR="lime"]//ermittle oktalwert fuer owner[/COLOR]
		printf([COLOR="red"]"inode protection mode in octal: %o\n"[/COLOR], oktalwertrechte);
		
		cout << [COLOR="red"]"Dateirechte nach folgender Reihenfolge directory owner group others"[/COLOR] << endl;	
		
		int type_of_file;	
		type_of_file = (((zahl/8)/8)/8);			                                              [COLOR="lime"]//ermittle oktalzahl fuer dateityp[/COLOR]

		if (type_of_file == 040)				                                              [COLOR="lime"]//wenn dateityp den wert 40 hat gebe "d" fuer directory aus[/COLOR]
			cout << [COLOR="red"]"d"[/COLOR];
		else
			cout << [COLOR="red"]"-"[/COLOR];
		[COLOR="lime"]//rechte des eigentuemers[/COLOR]
		if ((owner/4)%2)								                      [COLOR="lime"]//ermittlen der zugriffsrechte[/COLOR] 
			cout << [COLOR="red"]"r"[/COLOR];
		else
			cout << [COLOR="red"]"-"[/COLOR];
		if ((owner/2)%2)
			cout << [COLOR="red"]"w"[/COLOR];
		else
			cout << [COLOR="red"]"-"[/COLOR];
		if (owner%2)
			cout << [COLOR="red"]"x"[/COLOR];
		else
			cout << [COLOR="red"]"-"[/COLOR];
		[COLOR="lime"]//rechte der group[/COLOR]
		if ((group/4)%2)
				cout << [COLOR="red"]"r"[/COLOR];
			else 
				cout << [COLOR="red"]"-"[/COLOR];
			if ((group/2)%2)
				cout << [COLOR="red"]"w"[/COLOR];
			else
				cout << [COLOR="red"]"-"[/COLOR];
			if (group%2)
				cout << [COLOR="red"]"x"[/COLOR];
			else
				cout << [COLOR="red"]"-"[/COLOR];
        [COLOR="lime"]//rechte der anderen[/COLOR]        
		if ((other/4)%2)
				cout << [COLOR="red"]"r"[/COLOR];
			else 
				cout << [COLOR="red"]"-"[/COLOR];
			if ((other/2)%2)
				cout << [COLOR="red"]"w"[/COLOR];
			else
				cout << [COLOR="red"]"-"[/COLOR];
			if (other%2)
				cout << [COLOR="red"]"x"[/COLOR];
			else
				cout << [COLOR="red"]"-"[/COLOR];
			cout << endl;

	}
	else
	{
	cout << [COLOR="red"]"Fehler beim Funktionsaufruf stat()! Datei oder Verzeichnis nicht vorhanden!"[/COLOR] << endl;
}
}
 
Zuletzt bearbeitet:
Zurück
Oben Unten