Universität Ulm, Fakultät für Mathematik und Wirtschaftswissenschaften, SAI

Lösung zu Blatt 10 der Systemnahe Software I (WS 97/98)

15 LS

myls.c

/* Blatt 10 - Soft1 97/98 - ls -alid */

#include <dirent.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "flags.h"
#include "names.h"

extern char *ctime();		/* wandelte Zeitstempel in Klartext um	*/

static char *getmtime(struct stat st) {	
   char *res = ctime(&st.st_mtime);     /* Achtung ctime erzeugt noch ein \n */
   res[strlen(res)-1] = 0;		/* Newline zu 0 Byte		*/
   res += 4;				/* Namen des Tages ueberspringen */
   return res;
}

static void list(char *file) {
   struct stat st;
   if (stat(file, &st)) {
      fprintf(stderr, "Error: can't stat %s\n", file);
      exit(2);
   }
   printf("%10ld ", st.st_ino);
   flags(st);				/* Ausgabe der Dir.+Rechteflags	*/
   printf(" %3ld", st.st_nlink);		/* Linkcounter	*/
   printf(" %-8s", username(st.st_uid));	/* Benutzername	*/
   printf(" %-8s", groupname(st.st_gid));	/* Grupppenname	*/
   printf(" %7ld", st.st_size);			/* Dateigroesse*/
   printf(" %s", getmtime(st));		/* Ausgabe der Modificationzeit	*/
   printf(" %s\n",file);		/* Dateiname */
}

void main(int argc, char *argv[]) {
   if (argc == 1) {
      DIR *dp;			/* Zeiger auf geoeffnetes Dir.	  */
      struct dirent *entry;	/* Zeiger auf einen Eintrag	  */
      if (!(dp = opendir(".")))	/* aktuelles Directory oeffnen	  */
	 perror("."),
	 exit(1);
      while ((entry = readdir(dp)))/* ueber alle Eintraege	  */
	 list(entry->d_name);	/* Anzeige der Dateieigenschaften */
      closedir(dp);
   } else {
      int i;
      for (i = 1; i < argc; i++) list(argv[i]); /* Gib alles Parameter aus */
   }
   exit(0);
}

names.c

/* Blatt 10 - Soft1 97/98 - ls -alid */

#include <pwd.h> /* Fuer die Usernamen */
#include <grp.h> /* Fuer die Gruppennamen */

char *username(int uid) {
   struct passwd *entry = getpwuid(uid);
   return entry->pw_name;
}

char *groupname(int gid) {
   struct group *entry = getgrgid(gid);
   return entry->gr_name;
}

names.h

/* Blatt 10 - Soft1 97/98 - ls -alid */

char *username(int uid);
char *groupname(int gid);

flags.c

/* Blatt 10 - Soft1 97/98 - ls -alid */

#include "flags.h"
#include <sys/types.h>
#include <sys/stat.h>

#define DIM(x) (sizeof((x)) / sizeof(*(x)))

typedef struct flags {
   char flag;			/* Auszugebender Character	*/
   int mask;			/* zu verknuepfendes Bitmuster	*/
} FLAGS;

static FLAGS rights[] = {	/* Tabelle der einzelnen Rechte	*/
   { 'r', S_IRUSR },		/* fuer den Besitzer der Datei	*/
   { 'w', S_IWUSR },
   { 'x', S_IXUSR },
   { 'r', S_IRGRP },		/* fuer die Gruppe		*/
   { 'w', S_IWGRP },
   { 'x', S_IXGRP },
   { 'r', S_IROTH },		/* fuer den Rest der Welt	*/
   { 'w', S_IWOTH },
   { 'x', S_IXOTH }
};

void flags(struct stat st) {
   int i;
   switch (st.st_mode & S_IFMT) {
      case S_IFBLK: putchar('b'); break;  /* Block */
      case S_IFCHR: putchar('c'); break;  /* Char */
      case S_IFDIR: putchar('d'); break;  /* Dir */
      case S_IFLNK: putchar('l'); break;  /* Link */
      case S_IFIFO: putchar('p'); break;  /* FIFO */
      case S_IFSOCK: putchar('s'); break; /* Socket */
      case S_IFREG: putchar('-'); break;  /* Regular */
      default: putchar('?'); break;
   }
   for (i = 0; i < DIM(rights); i++)	/* Abarbeitung der Rechteflags	*/
      if (rights[i].mask & st.st_mode)
	 putchar(rights[i].flag);
      else
	 putchar('-');
}

flags.h

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

/* Gibt die Art und die Zugriffsrechte einer Datei aus. */

void flags(struct stat st);

Makefile

# Makefile ls

MAIN=myls
CC=gcc
LIB=
FLAGS = -Wall

OBJ=$(MAIN).o flags.o names.o
TOBJ=testsock.o sock.o

main:	$(OBJ)
	$(CC) $(FLAGS) $(LIB) -o $(MAIN) $(OBJ)

.c.o:
	$(CC) $(FLAGS) -c $*.c
clean:
	rm -f $(OBJ) $(TOBJ) core

Universität Fakultät SAI

Ingo Melzer, 20. January 1998