]> pd.if.org Git - pdutils/blob - posix/pwd/pwd.c
implemented pwd
[pdutils] / posix / pwd / pwd.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <unistd.h>
5 #include <limits.h>
6 #include <string.h>
7
8 static int has_dot_or_dotdot(char *path) {
9         if (!path) return 0;
10
11         while (*path) {
12                 if (*path == '/') {
13                         path++;
14                         continue;
15                 }
16                 if (*path == '.') {
17                         path++;
18                         if (*path == '.') path++;
19                         switch (path[0]) {
20                                 case '/':
21                                 case 0:
22                                         return 1;
23                                 default:
24                                         break;
25                         }
26                 }
27                 while (*path && *path != '/') {
28                         path++;
29                 }
30         }
31         return 0;
32 }
33
34 static void fillcwd(char *s, size_t n) {
35         if (!getcwd(s, n)) {
36                 switch (errno) {
37                         case ERANGE:
38                                 fprintf(stderr, "pwd: path too long\n");
39                                 exit(1);
40                         default:
41                                 perror("pwd");
42                                 exit(1);
43                 }
44         }
45 }
46
47 int main(int ac, char *av[]) {
48         int cleansym = 0;
49         char cwd[PATH_MAX];
50         char *pwd;
51         char *envpwd;
52         int arg;
53
54         for (arg=1; arg < ac; arg++) {
55                 if (av[arg][0] == '-') {
56                        if (av[arg][1] == 'P' && av[arg][2] == 0) {
57                                cleansym = 1;
58                        } else if (av[arg][1] == 'L' && av[arg][2] == 0) {
59                                cleansym = 0;
60                        }
61                 } else {
62                         fprintf(stderr, "usage: pwd [-L|-P]\n");
63                         exit(1);
64                 }
65         }
66
67         if (!getcwd(cwd, sizeof cwd)) {
68                 switch (errno) {
69                         case ERANGE:
70                                 fprintf(stderr, "pwd: path too long\n");
71                                 exit(1);
72                         default:
73                                 perror("pwd");
74                                 exit(1);
75                 }
76         }
77         pwd = cwd;
78
79         if (!cleansym) {
80                 envpwd = getenv("PWD");
81                 if (envpwd && !has_dot_or_dotdot(envpwd)) {
82                         if (chdir(envpwd) != -1) {
83                                 fillcwd(cwd, sizeof cwd);
84                                 if (strcmp(cwd, envpwd)) {
85                                         pwd = envpwd;
86                                 }
87                         }
88                 }
89         }
90
91         printf("%s\n", pwd);
92         return 0;
93 }
94