Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/preroot/getpreroot.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
/*
24
* AT&T Bell Laboratories
25
* return the real absolute pathname of the preroot dir for cmd
26
* if cmd==0 then current preroot path returned
27
*/
28
29
#include <ast.h>
30
#include <preroot.h>
31
32
#if FS_PREROOT
33
34
#include <ast_dir.h>
35
#include <ls.h>
36
#include <error.h>
37
#include <stdio.h>
38
39
#ifndef ERANGE
40
#define ERANGE E2BIG
41
#endif
42
43
#define ERROR(e) {errno=e;goto error;}
44
45
char*
46
getpreroot(char* path, const char* cmd)
47
{
48
register int c;
49
register FILE* fp;
50
register char* p;
51
char buf[PATH_MAX];
52
53
if (!path) path = buf;
54
if (cmd)
55
{
56
sfsprintf(buf, sizeof(buf), "set x `%s= %s - </dev/null 2>&1`\nwhile :\ndo\nshift\ncase $# in\n[012]) break ;;\nesac\ncase \"$1 $2\" in\n\"+ %s\") echo $3; exit ;;\nesac\ndone\necho\n", PR_SILENT, cmd, PR_COMMAND);
57
if (!(fp = popen(buf, "rug"))) return(0);
58
for (p = path; (c = getc(fp)) != EOF && c != '\n'; *p++ = c);
59
*p = 0;
60
pclose(fp);
61
if (path == p) return(0);
62
return(path == buf ? strdup(path) : path);
63
}
64
else
65
{
66
char* d;
67
DIR* dirp = 0;
68
int namlen;
69
int euid;
70
int ruid;
71
struct dirent* entry;
72
struct stat* cur;
73
struct stat* par;
74
struct stat* tmp;
75
struct stat curst;
76
struct stat parst;
77
struct stat tstst;
78
char dots[PATH_MAX];
79
80
cur = &curst;
81
par = &parst;
82
if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
83
if (stat(PR_REAL, cur) || stat("/", par) || cur->st_dev == par->st_dev && cur->st_ino == par->st_ino) ERROR(ENOTDIR);
84
85
/*
86
* like getcwd() but starting at the preroot
87
*/
88
89
d = dots;
90
*d++ = '/';
91
p = path + PATH_MAX - 1;
92
*p = 0;
93
for (;;)
94
{
95
tmp = cur;
96
cur = par;
97
par = tmp;
98
if ((d - dots) > (PATH_MAX - 4)) ERROR(ERANGE);
99
*d++ = '.';
100
*d++ = '.';
101
*d = 0;
102
if (!(dirp = opendir(dots))) ERROR(errno);
103
#if !_dir_ok || _mem_dd_fd_DIR
104
if (fstat(dirp->dd_fd, par)) ERROR(errno);
105
#else
106
if (stat(dots, par)) ERROR(errno);
107
#endif
108
*d++ = '/';
109
if (par->st_dev == cur->st_dev)
110
{
111
if (par->st_ino == cur->st_ino)
112
{
113
closedir(dirp);
114
*--p = '/';
115
if (ruid != euid) setuid(euid);
116
if (path == buf) return(strdup(p));
117
if (path != p)
118
{
119
d = path;
120
while (*d++ = *p++);
121
}
122
return(path);
123
}
124
#ifdef D_FILENO
125
while (entry = readdir(dirp))
126
if (D_FILENO(entry) == cur->st_ino)
127
{
128
namlen = D_NAMLEN(entry);
129
goto found;
130
}
131
#endif
132
133
/*
134
* this fallthrough handles logical naming
135
*/
136
137
rewinddir(dirp);
138
}
139
do
140
{
141
if (!(entry = readdir(dirp))) ERROR(ENOENT);
142
namlen = D_NAMLEN(entry);
143
if ((d - dots) > (PATH_MAX - 1 - namlen)) ERROR(ERANGE);
144
memcpy(d, entry->d_name, namlen + 1);
145
if (stat(dots, &tstst)) ERROR(errno);
146
} while (tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
147
found:
148
if (*p) *--p = '/';
149
if ((p -= namlen) <= (path + 1)) ERROR(ERANGE);
150
memcpy(p, entry->d_name, namlen);
151
closedir(dirp);
152
dirp = 0;
153
}
154
error:
155
if (dirp) closedir(dirp);
156
if (ruid != euid) setuid(euid);
157
}
158
return(0);
159
}
160
161
#else
162
163
NoN(getpreroot)
164
165
#endif
166
167