xref: /inferno-os/lib9/dirstat-posix.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <pwd.h>
5 #include <grp.h>
6 
7 static char nullstring[] = "";
8 static char Enovmem[] = "out of memory";
9 
10 static Dir*
statconv(struct stat * s,char * name)11 statconv(struct stat *s, char *name)
12 {
13 	struct passwd *p;
14 	struct group *g;
15 	Dir *dir;
16 	int str;
17 	char *n;
18 
19 	str = 0;
20 	p = getpwuid(s->st_uid);
21 	if(p)
22 		str += strlen(p->pw_name)+1;
23 	g = getgrgid(s->st_gid);
24 	if(g)
25 		str += strlen(g->gr_name)+1;
26 	dir = malloc(sizeof(Dir)+str);
27 	if(dir == nil){
28 		werrstr(Enovmem);
29 		return nil;
30 	}
31 	n = (char*)dir+sizeof(Dir);
32 	dir->name = name;
33 	dir->uid = dir->gid = dir->muid = nullstring;
34 	if(p){
35 		dir->uid = n;
36 		strcpy(n, p->pw_name);
37 		n += strlen(p->pw_name)+1;
38 	}
39 	if(g){
40 		dir->gid = n;
41 		strcpy(n, g->gr_name);
42 	}
43 	dir->qid.type = S_ISDIR(s->st_mode)? QTDIR: QTFILE;
44 	dir->qid.path = s->st_ino;
45 	dir->qid.vers = s->st_mtime;
46 	dir->mode = (dir->qid.type<<24)|(s->st_mode&0777);
47 	dir->atime = s->st_atime;
48 	dir->mtime = s->st_mtime;
49 	dir->length = s->st_size;
50 	dir->dev = s->st_dev;
51 	dir->type = S_ISFIFO(s->st_mode)? '|': 'M';
52 	return dir;
53 }
54 
55 Dir*
dirfstat(int fd)56 dirfstat(int fd)
57 {
58 	struct stat sbuf;
59 
60 	if(fstat(fd, &sbuf) < 0)
61 		return nil;
62 	return statconv(&sbuf, nullstring);
63 }
64 
65 Dir*
dirstat(char * f)66 dirstat(char *f)
67 {
68 	struct stat sbuf;
69 	char *p;
70 
71 	if(stat(f, &sbuf) < 0)
72 		return nil;
73 	p = strrchr(f, '/');
74 	if(p)
75 		p++;
76 	else
77 		p = nullstring;
78 	return statconv(&sbuf, p);
79 }
80