1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
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
43 #define ERROR(e) {errno=e;goto error;}
46 getpreroot(char* path
, const char* cmd
)
53 if (!path
) path
= buf
;
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
);
61 if (path
== p
) return(0);
62 return(path
== buf
? strdup(path
) : path
);
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
);
86 * like getcwd() but starting at the preroot
91 p
= path
+ PATH_MAX
- 1;
98 if ((d
- dots
) > (PATH_MAX
- 4)) ERROR(ERANGE
);
102 if (!(dirp
= opendir(dots
))) ERROR(errno
);
103 #if !_dir_ok || _mem_dd_fd_DIR
104 if (fstat(dirp
->dd_fd
, par
)) ERROR(errno
);
106 if (stat(dots
, par
)) ERROR(errno
);
109 if (par
->st_dev
== cur
->st_dev
)
111 if (par
->st_ino
== cur
->st_ino
)
115 if (ruid
!= euid
) setuid(euid
);
116 if (path
== buf
) return(strdup(p
));
125 while (entry
= readdir(dirp
))
126 if (D_FILENO(entry
) == cur
->st_ino
)
128 namlen
= D_NAMLEN(entry
);
134 * this fallthrough handles logical naming
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
);
149 if ((p
-= namlen
) <= (path
+ 1)) ERROR(ERANGE
);
150 memcpy(p
, entry
->d_name
, namlen
);
155 if (dirp
) closedir(dirp
);
156 if (ruid
!= euid
) setuid(euid
);