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