diff options
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/cat.c | 54 | ||||
-rw-r--r-- | coreutils/chgrp.c | 89 | ||||
-rw-r--r-- | coreutils/chmod.c | 163 | ||||
-rw-r--r-- | coreutils/chown.c | 63 | ||||
-rw-r--r-- | coreutils/chroot.c | 32 | ||||
-rw-r--r-- | coreutils/cp.c | 89 | ||||
-rw-r--r-- | coreutils/date.c | 305 | ||||
-rw-r--r-- | coreutils/dd.c | 307 | ||||
-rw-r--r-- | coreutils/df.c | 103 | ||||
-rw-r--r-- | coreutils/length.c | 13 | ||||
-rw-r--r-- | coreutils/ln.c | 52 | ||||
-rw-r--r-- | coreutils/ls.c | 542 | ||||
-rw-r--r-- | coreutils/mkdir.c | 58 | ||||
-rw-r--r-- | coreutils/mknod.c | 52 | ||||
-rw-r--r-- | coreutils/mv.c | 38 | ||||
-rw-r--r-- | coreutils/printf.c | 531 | ||||
-rw-r--r-- | coreutils/pwd.c | 18 | ||||
-rw-r--r-- | coreutils/rm.c | 30 | ||||
-rw-r--r-- | coreutils/rmdir.c | 17 | ||||
-rw-r--r-- | coreutils/sleep.c | 15 | ||||
-rw-r--r-- | coreutils/sync.c | 11 | ||||
-rw-r--r-- | coreutils/touch.c | 20 |
22 files changed, 2602 insertions, 0 deletions
diff --git a/coreutils/cat.c b/coreutils/cat.c new file mode 100644 index 000000000..12faf55ab --- /dev/null +++ b/coreutils/cat.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * Mini Cat implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "internal.h" | ||
23 | #include <stdio.h> | ||
24 | |||
25 | const char cat_usage[] = "[file ...]"; | ||
26 | |||
27 | extern int cat_more_main(int argc, char **argv) | ||
28 | { | ||
29 | int c; | ||
30 | FILE *file = stdin; | ||
31 | |||
32 | if (argc < 2) { | ||
33 | fprintf(stderr, "Usage: %s %s", *argv, cat_usage); | ||
34 | return 1; | ||
35 | } | ||
36 | argc--; | ||
37 | argv++; | ||
38 | |||
39 | while (argc-- > 0) { | ||
40 | file = fopen(*argv, "r"); | ||
41 | if (file == NULL) { | ||
42 | name_and_error(*argv); | ||
43 | return 1; | ||
44 | } | ||
45 | while ((c = getc(file)) != EOF) | ||
46 | putc(c, stdout); | ||
47 | fclose(file); | ||
48 | fflush(stdout); | ||
49 | |||
50 | argc--; | ||
51 | argv++; | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c new file mode 100644 index 000000000..038c665dd --- /dev/null +++ b/coreutils/chgrp.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * Mini chgrp implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "internal.h" | ||
23 | #include <grp.h> | ||
24 | #include <stdio.h> | ||
25 | |||
26 | const char chgrp_usage[] = "chgrp [OPTION]... GROUP FILE...\n" | ||
27 | "Change the group membership of each FILE to GROUP.\n" | ||
28 | "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n"; | ||
29 | |||
30 | int chgrp_main(int argc, char **argv) | ||
31 | { | ||
32 | const char *cp; | ||
33 | int gid; | ||
34 | struct group *grp; | ||
35 | struct stat statBuf; | ||
36 | |||
37 | if (argc < 2) { | ||
38 | fprintf(stderr, "Usage: %s %s", *argv, chgrp_usage); | ||
39 | return 1; | ||
40 | } | ||
41 | argc--; | ||
42 | argv++; | ||
43 | |||
44 | cp = argv[1]; | ||
45 | if (isDecimal(*cp)) { | ||
46 | gid = 0; | ||
47 | while (isDecimal(*cp)) | ||
48 | gid = gid * 10 + (*cp++ - '0'); | ||
49 | if (*cp) { | ||
50 | fprintf(stderr, "Bad gid value\n"); | ||
51 | return -1; | ||
52 | } | ||
53 | } else { | ||
54 | grp = getgrnam(cp); | ||
55 | if (grp == NULL) { | ||
56 | fprintf(stderr, "Unknown group name\n"); | ||
57 | return -1; | ||
58 | } | ||
59 | gid = grp->gr_gid; | ||
60 | } | ||
61 | argc--; | ||
62 | argv++; | ||
63 | while (argc-- > 1) { | ||
64 | argv++; | ||
65 | if ((stat(*argv, &statBuf) < 0) || | ||
66 | (chown(*argv, statBuf.st_uid, gid) < 0)) { | ||
67 | perror(*argv); | ||
68 | } | ||
69 | } | ||
70 | return 1; | ||
71 | } | ||
72 | |||
73 | |||
74 | |||
75 | |||
76 | |||
77 | |||
78 | |||
79 | |||
80 | |||
81 | #if 0 | ||
82 | int | ||
83 | recursive(const char *fileName, BOOL followLinks, const char *pattern, | ||
84 | int (*fileAction) (const char *fileName, | ||
85 | const struct stat * statbuf), | ||
86 | int (*dirAction) (const char *fileName, | ||
87 | const struct stat * statbuf)) | ||
88 | |||
89 | #endif | ||
diff --git a/coreutils/chmod.c b/coreutils/chmod.c new file mode 100644 index 000000000..225c92d10 --- /dev/null +++ b/coreutils/chmod.c | |||
@@ -0,0 +1,163 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <unistd.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include "internal.h" | ||
6 | |||
7 | const char chmod_usage[] = "chmod [-R] mode file [file ...]\n" | ||
8 | "\nmode may be an octal integer representing the bit pattern for the\n" | ||
9 | "\tnew mode, or a symbolic value matching the pattern\n" | ||
10 | "\t[ugoa]{+|-|=}[rwxst] .\n" | ||
11 | "\t\tu:\tUser\n" | ||
12 | "\t\tg:\tGroup\n" | ||
13 | "\t\to:\tOthers\n" | ||
14 | "\t\ta:\tAll\n" | ||
15 | "\n" | ||
16 | "\n+:\tAdd privilege\n" | ||
17 | "\n-:\tRemove privilege\n" | ||
18 | "\n=:\tSet privilege\n" | ||
19 | "\n" | ||
20 | "\t\tr:\tRead\n" | ||
21 | "\t\tw:\tWrite\n" | ||
22 | "\t\tx:\tExecute\n" | ||
23 | "\t\ts:\tSet User ID\n" | ||
24 | "\t\tt:\t\"Sticky\" Text\n" | ||
25 | "\n" | ||
26 | "\tModes may be concatenated, as in \"u=rwx,g=rx,o=rx,-t,-s\n" | ||
27 | "\n" | ||
28 | "\t-R:\tRecursively change the mode of all files and directories\n" | ||
29 | "\t\tunder the argument directory."; | ||
30 | |||
31 | int | ||
32 | parse_mode( | ||
33 | const char * s | ||
34 | ,mode_t * or | ||
35 | ,mode_t * and | ||
36 | ,int * group_execute) | ||
37 | { | ||
38 | /* [ugoa]{+|-|=}[rwxstl] */ | ||
39 | mode_t mode = 0; | ||
40 | mode_t groups = S_ISVTX; | ||
41 | char type; | ||
42 | char c; | ||
43 | |||
44 | do { | ||
45 | for ( ; ; ) { | ||
46 | switch ( c = *s++ ) { | ||
47 | case '\0': | ||
48 | return -1; | ||
49 | case 'u': | ||
50 | groups |= S_ISUID|S_IRWXU; | ||
51 | continue; | ||
52 | case 'g': | ||
53 | groups |= S_ISGID|S_IRWXG; | ||
54 | continue; | ||
55 | case 'o': | ||
56 | groups |= S_IRWXO; | ||
57 | continue; | ||
58 | case 'a': | ||
59 | groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; | ||
60 | continue; | ||
61 | case '+': | ||
62 | case '=': | ||
63 | case '-': | ||
64 | type = c; | ||
65 | if ( groups == S_ISVTX ) /* The default is "all" */ | ||
66 | groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; | ||
67 | break; | ||
68 | default: | ||
69 | if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { | ||
70 | *and = 0; | ||
71 | *or = strtol(--s, 0, 010); | ||
72 | return 0; | ||
73 | } | ||
74 | else | ||
75 | return -1; | ||
76 | } | ||
77 | break; | ||
78 | } | ||
79 | |||
80 | while ( (c = *s++) != '\0' ) { | ||
81 | switch ( c ) { | ||
82 | case ',': | ||
83 | break; | ||
84 | case 'r': | ||
85 | mode |= S_IRUSR|S_IRGRP|S_IROTH; | ||
86 | continue; | ||
87 | case 'w': | ||
88 | mode |= S_IWUSR|S_IWGRP|S_IWOTH; | ||
89 | continue; | ||
90 | case 'x': | ||
91 | mode |= S_IXUSR|S_IXGRP|S_IXOTH; | ||
92 | continue; | ||
93 | case 's': | ||
94 | if ( group_execute != 0 && (groups & S_IRWXG) ) { | ||
95 | if ( *group_execute < 0 ) | ||
96 | return -1; | ||
97 | if ( type != '-' ) { | ||
98 | mode |= S_IXGRP; | ||
99 | *group_execute = 1; | ||
100 | } | ||
101 | } | ||
102 | mode |= S_ISUID|S_ISGID; | ||
103 | continue; | ||
104 | case 'l': | ||
105 | if ( *group_execute > 0 ) | ||
106 | return -1; | ||
107 | if ( type != '-' ) { | ||
108 | *and &= ~S_IXGRP; | ||
109 | *group_execute = -1; | ||
110 | } | ||
111 | mode |= S_ISGID; | ||
112 | groups |= S_ISGID; | ||
113 | continue; | ||
114 | case 't': | ||
115 | mode |= S_ISVTX; | ||
116 | continue; | ||
117 | default: | ||
118 | return -1; | ||
119 | } | ||
120 | break; | ||
121 | } | ||
122 | switch ( type ) { | ||
123 | case '=': | ||
124 | *and &= ~(groups); | ||
125 | /* fall through */ | ||
126 | case '+': | ||
127 | *or |= mode & groups; | ||
128 | break; | ||
129 | case '-': | ||
130 | *and &= ~(mode & groups); | ||
131 | *or &= *and; | ||
132 | break; | ||
133 | } | ||
134 | } while ( c == ',' ); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | extern int | ||
139 | chmod_main(struct FileInfo * i, int argc, char * * argv) | ||
140 | { | ||
141 | i->andWithMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; | ||
142 | i->orWithMode = 0; | ||
143 | |||
144 | while ( argc >= 3 ) { | ||
145 | if ( parse_mode(argv[1], &i->orWithMode, &i->andWithMode, 0) | ||
146 | == 0 ) { | ||
147 | argc--; | ||
148 | argv++; | ||
149 | } | ||
150 | else if ( strcmp(argv[1], "-R") == 0 ) { | ||
151 | i->recursive = 1; | ||
152 | argc--; | ||
153 | argv++; | ||
154 | } | ||
155 | else | ||
156 | break; | ||
157 | } | ||
158 | |||
159 | i->changeMode = 1; | ||
160 | i->complainInPostProcess = 1; | ||
161 | |||
162 | return monadic_main(i, argc, argv); | ||
163 | } | ||
diff --git a/coreutils/chown.c b/coreutils/chown.c new file mode 100644 index 000000000..a611f92f1 --- /dev/null +++ b/coreutils/chown.c | |||
@@ -0,0 +1,63 @@ | |||
1 | #include "internal.h" | ||
2 | #include <pwd.h> | ||
3 | #include <grp.h> | ||
4 | #include <string.h> | ||
5 | #include <stdio.h> | ||
6 | |||
7 | const char chown_usage[] = "chown [-R] user-name file [file ...]\n" | ||
8 | "\n\tThe group list is kept in the file /etc/groups.\n\n" | ||
9 | "\t-R:\tRecursively change the mode of all files and directories\n" | ||
10 | "\t\tunder the argument directory."; | ||
11 | |||
12 | int | ||
13 | parse_user_name(const char * s, struct FileInfo * i) | ||
14 | { | ||
15 | struct passwd * p; | ||
16 | char * dot = strchr(s, '.'); | ||
17 | |||
18 | if (! dot ) | ||
19 | dot = strchr(s, ':'); | ||
20 | |||
21 | if ( dot ) | ||
22 | *dot = '\0'; | ||
23 | |||
24 | if ( (p = getpwnam(s)) == 0 ) { | ||
25 | fprintf(stderr, "%s: no such user.\n", s); | ||
26 | return 1; | ||
27 | } | ||
28 | i->userID = p->pw_uid; | ||
29 | |||
30 | if ( dot ) { | ||
31 | struct group * g = getgrnam(++dot); | ||
32 | if ( g == 0 ) { | ||
33 | fprintf(stderr, "%s: no such group.\n", dot); | ||
34 | return 1; | ||
35 | } | ||
36 | i->groupID = g->gr_gid; | ||
37 | i->changeGroupID = 1; | ||
38 | } | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | extern int | ||
43 | chown_main(struct FileInfo * i, int argc, char * * argv) | ||
44 | { | ||
45 | int status; | ||
46 | |||
47 | while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) { | ||
48 | i->recursive = 1; | ||
49 | argc--; | ||
50 | argv++; | ||
51 | } | ||
52 | |||
53 | if ( (status = parse_user_name(argv[1], i)) != 0 ) | ||
54 | return status; | ||
55 | |||
56 | argv++; | ||
57 | argc--; | ||
58 | |||
59 | i->changeUserID = 1; | ||
60 | i->complainInPostProcess = 1; | ||
61 | |||
62 | return monadic_main(i, argc, argv); | ||
63 | } | ||
diff --git a/coreutils/chroot.c b/coreutils/chroot.c new file mode 100644 index 000000000..ca0bfcf3f --- /dev/null +++ b/coreutils/chroot.c | |||
@@ -0,0 +1,32 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <unistd.h> | ||
4 | |||
5 | |||
6 | const char chroot_usage[] = "chroot directory [command]\n" | ||
7 | "Run a command with special root directory.\n"; | ||
8 | |||
9 | extern int | ||
10 | chroot_main (struct FileInfo *i, int argc, char **argv) | ||
11 | { | ||
12 | char *prog; | ||
13 | |||
14 | if (chroot (argv[1])) | ||
15 | { | ||
16 | name_and_error ("cannot chroot to that directory"); | ||
17 | return 1; | ||
18 | } | ||
19 | if (argc > 2) | ||
20 | { | ||
21 | execvp (argv[2], argv + 2); | ||
22 | } | ||
23 | else | ||
24 | { | ||
25 | prog = getenv ("SHELL"); | ||
26 | if (!prog) | ||
27 | prog = "/bin/sh"; | ||
28 | execlp (prog, prog, NULL); | ||
29 | } | ||
30 | name_and_error ("cannot exec"); | ||
31 | return 1; | ||
32 | } | ||
diff --git a/coreutils/cp.c b/coreutils/cp.c new file mode 100644 index 000000000..078a57c56 --- /dev/null +++ b/coreutils/cp.c | |||
@@ -0,0 +1,89 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <sys/fcntl.h> | ||
5 | #include <sys/param.h> | ||
6 | #include <errno.h> | ||
7 | |||
8 | const char cp_usage[] = "cp [-r] source-file destination-file\n" | ||
9 | "\t\tcp [-r] source-file [source-file ...] destination-directory\n" | ||
10 | "\n" | ||
11 | "\tCopy the source files to the destination.\n" | ||
12 | "\n" | ||
13 | "\t-r:\tRecursively copy all files and directories\n" | ||
14 | "\t\tunder the argument directory."; | ||
15 | |||
16 | extern int | ||
17 | cp_fn(const struct FileInfo * i) | ||
18 | { | ||
19 | int sourceFd; | ||
20 | int destinationFd; | ||
21 | const char * destination = i->destination; | ||
22 | struct stat destination_stat; | ||
23 | int status; | ||
24 | char buf[8192]; | ||
25 | char d[PATH_MAX]; | ||
26 | |||
27 | if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { | ||
28 | if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) | ||
29 | != 0 && errno != EEXIST ) { | ||
30 | name_and_error(destination); | ||
31 | return 1; | ||
32 | } | ||
33 | return 0; | ||
34 | } | ||
35 | if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { | ||
36 | name_and_error(i->source); | ||
37 | return 1; | ||
38 | } | ||
39 | if ( stat(destination, &destination_stat) == 0 ) { | ||
40 | if ( i->stat.st_ino == destination_stat.st_ino | ||
41 | && i->stat.st_dev == destination_stat.st_dev ) { | ||
42 | fprintf(stderr | ||
43 | ,"copy of %s to %s would copy file to itself.\n" | ||
44 | ,i->source | ||
45 | ,destination); | ||
46 | close(sourceFd); | ||
47 | return 1; | ||
48 | } | ||
49 | } | ||
50 | /* | ||
51 | * If the destination is a directory, create a file within it. | ||
52 | */ | ||
53 | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { | ||
54 | destination = join_paths( | ||
55 | d | ||
56 | ,i->destination | ||
57 | ,&i->source[i->directoryLength]); | ||
58 | |||
59 | if ( stat(destination, &destination_stat) == 0 ) { | ||
60 | if ( i->stat.st_ino == destination_stat.st_ino | ||
61 | && i->stat.st_dev == destination_stat.st_dev ) { | ||
62 | fprintf(stderr | ||
63 | ,"copy of %s to %s would copy file to itself.\n" | ||
64 | ,i->source | ||
65 | ,destination); | ||
66 | close(sourceFd); | ||
67 | return 1; | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | destinationFd = creat(destination, i->stat.st_mode & 07777); | ||
73 | |||
74 | while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { | ||
75 | if ( write(destinationFd, buf, status) != status ) { | ||
76 | name_and_error(destination); | ||
77 | close(sourceFd); | ||
78 | close(destinationFd); | ||
79 | return 1; | ||
80 | } | ||
81 | } | ||
82 | close(sourceFd); | ||
83 | close(destinationFd); | ||
84 | if ( status < 0 ) { | ||
85 | name_and_error(i->source); | ||
86 | return 1; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
diff --git a/coreutils/date.c b/coreutils/date.c new file mode 100644 index 000000000..a52a9a4a8 --- /dev/null +++ b/coreutils/date.c | |||
@@ -0,0 +1,305 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdlib.h> | ||
3 | #include <errno.h> | ||
4 | #include <sys/time.h> | ||
5 | #include <unistd.h> | ||
6 | #include <time.h> | ||
7 | #include <stdio.h> | ||
8 | #include <getopt.h> | ||
9 | |||
10 | |||
11 | /* This 'date' command supports only 2 time setting formats, | ||
12 | all the GNU strftime stuff (its in libc, lets use it), | ||
13 | setting time using UTC and displaying int, as well as | ||
14 | an RFC 822 complient date output for shell scripting | ||
15 | mail commands */ | ||
16 | |||
17 | const char date_usage[] = "date [-uR] [+FORMAT|+%f] [ [-s|-d] MMDDhhmm[[CC]YY]\n | [[[[CCYY.]MM.DD-]hh:mm[:ss]]]] ]"; | ||
18 | |||
19 | static struct option const long_options[] = | ||
20 | { | ||
21 | {"date", required_argument, NULL, 'd'}, | ||
22 | /* {"rfc-822", no_argument, NULL, 'R'}, | ||
23 | {"set", required_argument, NULL, 's'}, | ||
24 | {"uct", no_argument, NULL, 'u'}, | ||
25 | {"utc", no_argument, NULL, 'u'}, | ||
26 | {"universal", no_argument, NULL, 'u'}, */ | ||
27 | {NULL, 0, NULL, 0} | ||
28 | }; | ||
29 | |||
30 | |||
31 | |||
32 | /* Input parsing code is always bulky - used heavy duty libc stuff as | ||
33 | much as possible, missed out a lot of bounds checking */ | ||
34 | |||
35 | /* Default input handling to save suprising some people */ | ||
36 | |||
37 | struct tm * | ||
38 | date_conv_time(struct tm *tm_time, const char *t_string) { | ||
39 | int nr; | ||
40 | |||
41 | nr = sscanf(t_string, "%2d%2d%2d%2d%d", | ||
42 | &(tm_time->tm_mon), | ||
43 | &(tm_time->tm_mday), | ||
44 | &(tm_time->tm_hour), | ||
45 | &(tm_time->tm_min), | ||
46 | &(tm_time->tm_year)); | ||
47 | |||
48 | if(nr < 4 || nr > 5) { | ||
49 | fprintf(stderr, "date: invalid date `%s'\n", t_string); | ||
50 | exit(1); | ||
51 | } | ||
52 | |||
53 | /* correct for century - minor Y2K problem here? */ | ||
54 | if(tm_time->tm_year >= 1900) | ||
55 | tm_time->tm_year -= 1900; | ||
56 | /* adjust date */ | ||
57 | tm_time->tm_mon -= 1; | ||
58 | |||
59 | return(tm_time); | ||
60 | |||
61 | } | ||
62 | |||
63 | |||
64 | /* The new stuff for LRP */ | ||
65 | |||
66 | struct tm * | ||
67 | date_conv_ftime(struct tm *tm_time, const char *t_string) { | ||
68 | struct tm itm_time, jtm_time, ktm_time, \ | ||
69 | ltm_time, mtm_time, ntm_time; | ||
70 | |||
71 | itm_time = *tm_time; | ||
72 | jtm_time = *tm_time; | ||
73 | ktm_time = *tm_time; | ||
74 | ltm_time = *tm_time; | ||
75 | mtm_time = *tm_time; | ||
76 | ntm_time = *tm_time; | ||
77 | |||
78 | /* Parse input and assign appropriately to tm_time */ | ||
79 | |||
80 | if(sscanf(t_string, "%d:%d:%d", | ||
81 | &itm_time.tm_hour, | ||
82 | &itm_time.tm_min, | ||
83 | &itm_time.tm_sec) == 3 ) { | ||
84 | |||
85 | *tm_time = itm_time; | ||
86 | return(tm_time); | ||
87 | |||
88 | } else if (sscanf(t_string, "%d:%d", | ||
89 | &jtm_time.tm_hour, | ||
90 | &jtm_time.tm_min) == 2) { | ||
91 | |||
92 | *tm_time = jtm_time; | ||
93 | return(tm_time); | ||
94 | |||
95 | } else if (sscanf(t_string, "%d.%d-%d:%d:%d", | ||
96 | &ktm_time.tm_mon, | ||
97 | &ktm_time.tm_mday, | ||
98 | &ktm_time.tm_hour, | ||
99 | &ktm_time.tm_min, | ||
100 | &ktm_time.tm_sec) == 5) { | ||
101 | |||
102 | ktm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
103 | *tm_time = ktm_time; | ||
104 | return(tm_time); | ||
105 | |||
106 | } else if (sscanf(t_string, "%d.%d-%d:%d", | ||
107 | <m_time.tm_mon, | ||
108 | <m_time.tm_mday, | ||
109 | <m_time.tm_hour, | ||
110 | <m_time.tm_min) == 4) { | ||
111 | |||
112 | ltm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
113 | *tm_time = ltm_time; | ||
114 | return(tm_time); | ||
115 | |||
116 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d", | ||
117 | &mtm_time.tm_year, | ||
118 | &mtm_time.tm_mon, | ||
119 | &mtm_time.tm_mday, | ||
120 | &mtm_time.tm_hour, | ||
121 | &mtm_time.tm_min, | ||
122 | &mtm_time.tm_sec) == 6) { | ||
123 | |||
124 | mtm_time.tm_year -= 1900; /* Adjust years */ | ||
125 | mtm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
126 | *tm_time = mtm_time; | ||
127 | return(tm_time); | ||
128 | |||
129 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d", | ||
130 | &ntm_time.tm_year, | ||
131 | &ntm_time.tm_mon, | ||
132 | &ntm_time.tm_mday, | ||
133 | &ntm_time.tm_hour, | ||
134 | &ntm_time.tm_min) == 5) { | ||
135 | ntm_time.tm_year -= 1900; /* Adjust years */ | ||
136 | ntm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
137 | *tm_time = ntm_time; | ||
138 | return(tm_time); | ||
139 | |||
140 | } | ||
141 | |||
142 | fprintf(stderr, "date: invalid date `%s'\n", t_string); | ||
143 | |||
144 | exit(1); | ||
145 | |||
146 | } | ||
147 | |||
148 | |||
149 | void | ||
150 | date_err(void) { | ||
151 | fprintf(stderr, "date: only one date argument can be given at a time.\n"); | ||
152 | exit(1); | ||
153 | } | ||
154 | |||
155 | int | ||
156 | date_main(struct FileInfo * i, int argc, char * * argv) | ||
157 | { | ||
158 | char *date_str = NULL; | ||
159 | char *date_fmt = NULL; | ||
160 | char *t_buff; | ||
161 | int set_time = 0; | ||
162 | int rfc822 = 0; | ||
163 | int utc = 0; | ||
164 | int use_arg = 0; | ||
165 | int n_args; | ||
166 | time_t tm; | ||
167 | struct tm tm_time; | ||
168 | char optc; | ||
169 | |||
170 | /* Interpret command line args */ | ||
171 | |||
172 | |||
173 | while ((optc = getopt_long (argc, argv, "d:Rs:u", long_options, NULL)) | ||
174 | != EOF) { | ||
175 | switch (optc) { | ||
176 | case 0: | ||
177 | break; | ||
178 | |||
179 | case 'R': | ||
180 | rfc822 = 1; | ||
181 | break; | ||
182 | |||
183 | case 's': | ||
184 | set_time = 1; | ||
185 | if(date_str != NULL) date_err(); | ||
186 | date_str = optarg; | ||
187 | break; | ||
188 | |||
189 | case 'u': | ||
190 | utc = 1; | ||
191 | if (putenv ("TZ=UTC0") != 0) { | ||
192 | fprintf(stderr,"date: memory exhausted\n"); | ||
193 | return(1); | ||
194 | } | ||
195 | #if LOCALTIME_CACHE | ||
196 | tzset (); | ||
197 | #endif break; | ||
198 | |||
199 | case 'd': | ||
200 | use_arg = 1; | ||
201 | if(date_str != NULL) date_err(); | ||
202 | date_str = optarg; | ||
203 | break; | ||
204 | |||
205 | default: | ||
206 | usage(date_usage); | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | |||
212 | n_args = argc - optind; | ||
213 | |||
214 | while (n_args--){ | ||
215 | switch(argv[optind][0]) { | ||
216 | case '+': | ||
217 | /* Date format strings */ | ||
218 | if(date_fmt != NULL) { | ||
219 | fprintf(stderr, "date: only one date format can be given.\n"); | ||
220 | return(1); | ||
221 | } | ||
222 | date_fmt = &argv[optind][1]; | ||
223 | break; | ||
224 | |||
225 | case '\0': | ||
226 | break; | ||
227 | |||
228 | default: | ||
229 | /* Anything left over must be a date string to set the time */ | ||
230 | set_time = 1; | ||
231 | if(date_str != NULL) date_err(); | ||
232 | date_str = argv[optind]; | ||
233 | break; | ||
234 | } | ||
235 | optind++; | ||
236 | } | ||
237 | |||
238 | |||
239 | /* Now we have parsed all the information except the date format | ||
240 | which depends on whether the clock is being set or read */ | ||
241 | |||
242 | time(&tm); | ||
243 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); | ||
244 | /* Zero out fields - take her back to midnight!*/ | ||
245 | if(date_str != NULL) { | ||
246 | tm_time.tm_sec = 0; | ||
247 | tm_time.tm_min = 0; | ||
248 | tm_time.tm_hour = 0; | ||
249 | } | ||
250 | |||
251 | /* Process any date input to UNIX time since 1 Jan 1970 */ | ||
252 | if(date_str != NULL) { | ||
253 | |||
254 | if(strchr(date_str, ':') != NULL) { | ||
255 | date_conv_ftime(&tm_time, date_str); | ||
256 | } else { | ||
257 | date_conv_time(&tm_time, date_str); | ||
258 | } | ||
259 | |||
260 | /* Correct any day of week and day of year etc fields */ | ||
261 | tm = mktime(&tm_time); | ||
262 | if (tm < 0 ) { | ||
263 | fprintf(stderr, "date: invalid date `%s'\n", date_str); | ||
264 | exit(1); | ||
265 | } | ||
266 | |||
267 | /* if setting time, set it */ | ||
268 | if(set_time) { | ||
269 | if( stime(&tm) < 0) { | ||
270 | fprintf(stderr, "date: can't set date.\n"); | ||
271 | exit(1); | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /* Display output */ | ||
277 | |||
278 | /* Deal with format string */ | ||
279 | if(date_fmt == NULL) { | ||
280 | date_fmt = (rfc822 | ||
281 | ? (utc | ||
282 | ? "%a, %_d %b %Y %H:%M:%S GMT" | ||
283 | : "%a, %_d %b %Y %H:%M:%S %z") | ||
284 | : "%a %b %e %H:%M:%S %Z %Y"); | ||
285 | |||
286 | } else if ( *date_fmt == '\0' ) { | ||
287 | /* Imitate what GNU 'date' does with NO format string! */ | ||
288 | printf ("\n"); | ||
289 | return(0); | ||
290 | } | ||
291 | |||
292 | /* Handle special conversions */ | ||
293 | |||
294 | if( strncmp( date_fmt, "%f", 2) == 0 ) { | ||
295 | date_fmt = "%Y.%m.%d-%H:%M:%S"; | ||
296 | } | ||
297 | |||
298 | /* Print OUTPUT (after ALL that!) */ | ||
299 | t_buff = malloc(201); | ||
300 | strftime(t_buff, 200, date_fmt, &tm_time); | ||
301 | printf("%s\n", t_buff); | ||
302 | |||
303 | return(0); | ||
304 | |||
305 | } | ||
diff --git a/coreutils/dd.c b/coreutils/dd.c new file mode 100644 index 000000000..8f1b9d409 --- /dev/null +++ b/coreutils/dd.c | |||
@@ -0,0 +1,307 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1999 by David I. Bell | ||
3 | * Permission is granted to use, distribute, or modify this source, | ||
4 | * provided that this copyright notice remains intact. | ||
5 | * | ||
6 | * The "dd" command, originally taken from sash. | ||
7 | * | ||
8 | * Permission to distribute this code under the GPL has been granted. | ||
9 | * Majorly modified, and bugs fixed for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com> | ||
10 | */ | ||
11 | |||
12 | #include "internal.h" | ||
13 | #ifdef BB_DD | ||
14 | |||
15 | const char dd_usage[] = | ||
16 | "Copy a file, converting and formatting according to options\n\ | ||
17 | \n\ | ||
18 | usage: [if=name] [of=name] [bs=n] [count=n]\n\ | ||
19 | \tif=FILE\tread from FILE instead of stdin\n\ | ||
20 | \tof=FILE\twrite to FILE instead of stout\n\ | ||
21 | \tbs=n\tread and write N bytes at a time\n\ | ||
22 | \tcount=n\tcopy only n input blocks\n\ | ||
23 | \n\ | ||
24 | BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\n"; | ||
25 | |||
26 | |||
27 | #include <stdio.h> | ||
28 | #include <dirent.h> | ||
29 | #include <errno.h> | ||
30 | #include <fcntl.h> | ||
31 | #include <signal.h> | ||
32 | #include <time.h> | ||
33 | |||
34 | |||
35 | #define PAR_NONE 0 | ||
36 | #define PAR_IF 1 | ||
37 | #define PAR_OF 2 | ||
38 | #define PAR_BS 3 | ||
39 | #define PAR_COUNT 4 | ||
40 | |||
41 | |||
42 | typedef struct | ||
43 | { | ||
44 | const char * name; | ||
45 | int value; | ||
46 | } PARAM; | ||
47 | |||
48 | |||
49 | static const PARAM params[] = | ||
50 | { | ||
51 | {"if", PAR_IF}, | ||
52 | {"of", PAR_OF}, | ||
53 | {"bs", PAR_BS}, | ||
54 | {"count", PAR_COUNT}, | ||
55 | {NULL, PAR_NONE} | ||
56 | }; | ||
57 | |||
58 | |||
59 | static long getNum(const char * cp); | ||
60 | |||
61 | extern int | ||
62 | dd_main (struct FileInfo *unused, int argc, char **argv) | ||
63 | { | ||
64 | const char * str; | ||
65 | const PARAM * par; | ||
66 | const char * inFile; | ||
67 | const char * outFile; | ||
68 | char * cp; | ||
69 | int inFd; | ||
70 | int outFd; | ||
71 | int inCc=0; | ||
72 | int outCc; | ||
73 | int blockSize; | ||
74 | long count; | ||
75 | long intotal; | ||
76 | long outTotal; | ||
77 | unsigned char* buf; | ||
78 | unsigned char localBuf[BUF_SIZE]; | ||
79 | |||
80 | inFile = NULL; | ||
81 | outFile = NULL; | ||
82 | blockSize = 512; | ||
83 | count = 1; | ||
84 | |||
85 | |||
86 | while (--argc > 0) | ||
87 | { | ||
88 | str = *++argv; | ||
89 | cp = strchr(str, '='); | ||
90 | |||
91 | if (cp == NULL) | ||
92 | { | ||
93 | fprintf(stderr, "Bad dd argument\n"); | ||
94 | goto usage; | ||
95 | } | ||
96 | |||
97 | *cp++ = '\0'; | ||
98 | |||
99 | for (par = params; par->name; par++) | ||
100 | { | ||
101 | if (strcmp(str, par->name) == 0) | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | switch (par->value) | ||
106 | { | ||
107 | case PAR_IF: | ||
108 | if (inFile) | ||
109 | { | ||
110 | fprintf(stderr, "Multiple input files illegal\n"); | ||
111 | goto usage; | ||
112 | } | ||
113 | |||
114 | //fprintf(stderr, "if=%s\n", cp); | ||
115 | inFile = cp; | ||
116 | break; | ||
117 | |||
118 | case PAR_OF: | ||
119 | if (outFile) | ||
120 | { | ||
121 | fprintf(stderr, "Multiple output files illegal\n"); | ||
122 | goto usage; | ||
123 | } | ||
124 | |||
125 | //fprintf(stderr, "of=%s\n", cp); | ||
126 | outFile = cp; | ||
127 | break; | ||
128 | |||
129 | case PAR_BS: | ||
130 | blockSize = getNum(cp); | ||
131 | //fprintf(stderr, "bs=%d\n", blockSize); | ||
132 | |||
133 | if (blockSize <= 0) | ||
134 | { | ||
135 | fprintf(stderr, "Bad block size value\n"); | ||
136 | goto usage; | ||
137 | } | ||
138 | |||
139 | break; | ||
140 | |||
141 | case PAR_COUNT: | ||
142 | count = getNum(cp); | ||
143 | //fprintf(stderr, "count=%ld\n", count); | ||
144 | |||
145 | if (count < 0) | ||
146 | { | ||
147 | fprintf(stderr, "Bad count value\n"); | ||
148 | goto usage; | ||
149 | } | ||
150 | |||
151 | break; | ||
152 | |||
153 | default: | ||
154 | goto usage; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | buf = localBuf; | ||
159 | |||
160 | if (blockSize > sizeof(localBuf)) | ||
161 | { | ||
162 | buf = malloc(blockSize); | ||
163 | |||
164 | if (buf == NULL) | ||
165 | { | ||
166 | fprintf(stderr, "Cannot allocate buffer\n"); | ||
167 | return 1; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | intotal = 0; | ||
172 | outTotal = 0; | ||
173 | |||
174 | if (inFile == NULL) | ||
175 | inFd = STDIN; | ||
176 | else | ||
177 | inFd = open(inFile, 0); | ||
178 | |||
179 | if (inFd < 0) | ||
180 | { | ||
181 | perror(inFile); | ||
182 | |||
183 | if (buf != localBuf) | ||
184 | free(buf); | ||
185 | |||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | if (outFile == NULL) | ||
190 | outFd = STDOUT; | ||
191 | else | ||
192 | outFd = creat(outFile, 0666); | ||
193 | |||
194 | if (outFd < 0) | ||
195 | { | ||
196 | perror(outFile); | ||
197 | close(inFd); | ||
198 | |||
199 | if (buf != localBuf) | ||
200 | free(buf); | ||
201 | |||
202 | return 1; | ||
203 | } | ||
204 | |||
205 | while ( outTotal < count*blockSize ) | ||
206 | { | ||
207 | inCc = read(inFd, buf, blockSize); | ||
208 | if (inCc < 0) { | ||
209 | perror(inFile); | ||
210 | goto cleanup; | ||
211 | } | ||
212 | //fprintf(stderr, "read in =%d\n", inCc); | ||
213 | intotal += inCc; | ||
214 | cp = buf; | ||
215 | |||
216 | |||
217 | while ( intotal > outTotal ) | ||
218 | { | ||
219 | if (outTotal+inCc > count*blockSize) | ||
220 | inCc=count*blockSize-outTotal; | ||
221 | outCc = write(outFd, cp, inCc); | ||
222 | if (outCc < 0) | ||
223 | { | ||
224 | perror(outFile); | ||
225 | goto cleanup; | ||
226 | } | ||
227 | //fprintf(stderr, "wrote out =%d\n", outCc); | ||
228 | |||
229 | inCc -= outCc; | ||
230 | cp += outCc; | ||
231 | outTotal += outCc; | ||
232 | //fprintf(stderr, "outTotal=%ld\n", outTotal); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (inCc < 0) | ||
237 | perror(inFile); | ||
238 | |||
239 | cleanup: | ||
240 | close(inFd); | ||
241 | |||
242 | if (close(outFd) < 0) | ||
243 | perror(outFile); | ||
244 | |||
245 | if (buf != localBuf) | ||
246 | free(buf); | ||
247 | |||
248 | printf("%ld+%d records in\n", intotal / blockSize, | ||
249 | (intotal % blockSize) != 0); | ||
250 | |||
251 | printf("%ld+%d records out\n", outTotal / blockSize, | ||
252 | (outTotal % blockSize) != 0); | ||
253 | return 0; | ||
254 | usage: | ||
255 | |||
256 | fprintf(stderr, "%s", dd_usage); | ||
257 | return 1; | ||
258 | } | ||
259 | |||
260 | |||
261 | /* | ||
262 | * Read a number with a possible multiplier. | ||
263 | * Returns -1 if the number format is illegal. | ||
264 | */ | ||
265 | static long | ||
266 | getNum(const char * cp) | ||
267 | { | ||
268 | long value; | ||
269 | |||
270 | if (!isDecimal(*cp)) | ||
271 | return -1; | ||
272 | |||
273 | value = 0; | ||
274 | |||
275 | while (isDecimal(*cp)) | ||
276 | value = value * 10 + *cp++ - '0'; | ||
277 | |||
278 | switch (*cp++) | ||
279 | { | ||
280 | case 'k': | ||
281 | value *= 1024; | ||
282 | break; | ||
283 | |||
284 | case 'b': | ||
285 | value *= 512; | ||
286 | break; | ||
287 | |||
288 | case 'w': | ||
289 | value *= 2; | ||
290 | break; | ||
291 | |||
292 | case '\0': | ||
293 | return value; | ||
294 | |||
295 | default: | ||
296 | return -1; | ||
297 | } | ||
298 | |||
299 | if (*cp) | ||
300 | return -1; | ||
301 | |||
302 | return value; | ||
303 | } | ||
304 | |||
305 | #endif | ||
306 | /* END CODE */ | ||
307 | |||
diff --git a/coreutils/df.c b/coreutils/df.c new file mode 100644 index 000000000..a0692afc5 --- /dev/null +++ b/coreutils/df.c | |||
@@ -0,0 +1,103 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <mntent.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <sys/vfs.h> | ||
6 | |||
7 | const char df_usage[] = "df [filesystem ...]\n" | ||
8 | "\n" | ||
9 | "\tPrint the filesystem space used and space available.\n"; | ||
10 | |||
11 | |||
12 | static int | ||
13 | df(const char * device, const char * mountPoint) | ||
14 | { | ||
15 | struct statfs s; | ||
16 | long blocks_used; | ||
17 | long blocks_percent_used; | ||
18 | |||
19 | if ( statfs(mountPoint, &s) != 0 ) { | ||
20 | name_and_error(mountPoint); | ||
21 | return 1; | ||
22 | } | ||
23 | |||
24 | if ( s.f_blocks > 0 ) { | ||
25 | blocks_used = s.f_blocks - s.f_bfree; | ||
26 | blocks_percent_used = (long) | ||
27 | (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | ||
28 | |||
29 | /* | ||
30 | printf( | ||
31 | "%-20s %7ld %7ld %7ld %5ld%% %s\n" | ||
32 | ,device | ||
33 | ,s.f_blocks | ||
34 | ,s.f_blocks - s.f_bfree | ||
35 | ,s.f_bavail | ||
36 | ,blocks_percent_used | ||
37 | ,mountPoint); | ||
38 | */ | ||
39 | |||
40 | printf( | ||
41 | "%-20s %7.0f %7.0f %7.0f %5ld%% %s\n" | ||
42 | ,device | ||
43 | ,s.f_blocks * (s.f_bsize / 1024.0) | ||
44 | ,(s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0) | ||
45 | ,s.f_bavail * (s.f_bsize / 1024.0) | ||
46 | ,blocks_percent_used | ||
47 | ,mountPoint); | ||
48 | |||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | extern int | ||
55 | df_main(struct FileInfo * i, int argc, char * * argv) | ||
56 | { | ||
57 | static const char header[] = | ||
58 | "Filesystem 1024-blocks Used Available Capacity Mounted on\n"; | ||
59 | printf(header); | ||
60 | |||
61 | if ( argc > 1 ) { | ||
62 | struct mntent * mountEntry; | ||
63 | int status; | ||
64 | |||
65 | while ( argc > 1 ) { | ||
66 | if ( (mountEntry = findMountPoint(argv[1], "/etc/mtab")) == 0 | ||
67 | && (mountEntry = findMountPoint(argv[1], "/proc/mounts")) == 0 ) | ||
68 | { | ||
69 | fprintf(stderr, "%s: can't find mount point.\n" | ||
70 | ,argv[1]); | ||
71 | return 1; | ||
72 | } | ||
73 | status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir); | ||
74 | if ( status != 0 ) | ||
75 | return status; | ||
76 | argc--; | ||
77 | argv++; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | else { | ||
82 | FILE * mountTable; | ||
83 | struct mntent * mountEntry; | ||
84 | |||
85 | if ( (mountTable = setmntent("/etc/mtab", "r")) == 0 | ||
86 | && (mountTable = setmntent("/proc/mounts", "r")) == 0 | ||
87 | ) { | ||
88 | name_and_error("/etc/mtab"); | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
93 | int status = df( | ||
94 | mountEntry->mnt_fsname | ||
95 | ,mountEntry->mnt_dir); | ||
96 | if ( status != 0 ) | ||
97 | return status; | ||
98 | } | ||
99 | endmntent(mountTable); | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
diff --git a/coreutils/length.c b/coreutils/length.c new file mode 100644 index 000000000..284bbfdf9 --- /dev/null +++ b/coreutils/length.c | |||
@@ -0,0 +1,13 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <stdio.h> | ||
5 | |||
6 | const char length_usage[] = "length string"; | ||
7 | |||
8 | int | ||
9 | length_main(struct FileInfo * i, int argc, char * * argv) | ||
10 | { | ||
11 | printf("%d\n", strlen(argv[1])); | ||
12 | return 0; | ||
13 | } | ||
diff --git a/coreutils/ln.c b/coreutils/ln.c new file mode 100644 index 000000000..3e87b579e --- /dev/null +++ b/coreutils/ln.c | |||
@@ -0,0 +1,52 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <sys/param.h> | ||
5 | #include <errno.h> | ||
6 | |||
7 | const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n" | ||
8 | "\n" | ||
9 | "\tAdd a new name that refers to the same file as \"original-name\"\n" | ||
10 | "\n" | ||
11 | "\t-s:\tUse a \"symbolic\" link, instead of a \"hard\" link.\n" | ||
12 | "\t-f:\tRemove existing destination files.\n"; | ||
13 | |||
14 | int | ||
15 | ln_fn(const struct FileInfo * i) | ||
16 | { | ||
17 | int status = 0; | ||
18 | char d[PATH_MAX]; | ||
19 | const char * destination = i->destination; | ||
20 | |||
21 | if ( !i->makeSymbolicLink && (i->stat.st_mode & S_IFMT) == S_IFDIR ) { | ||
22 | fprintf(stderr, "Please use \"ln -s\" to link directories.\n"); | ||
23 | return 1; | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * If the destination is a directory, create a file within it. | ||
28 | */ | ||
29 | if ( is_a_directory(i->destination) ) { | ||
30 | destination = join_paths( | ||
31 | d | ||
32 | ,i->destination | ||
33 | ,&i->source[i->directoryLength]); | ||
34 | } | ||
35 | |||
36 | if ( i->force ) | ||
37 | status = ( unlink(destination) && errno != ENOENT ); | ||
38 | |||
39 | if ( status == 0 ) { | ||
40 | if ( i->makeSymbolicLink ) | ||
41 | status = symlink(i->source, destination); | ||
42 | else | ||
43 | status = link(i->source, destination); | ||
44 | } | ||
45 | |||
46 | if ( status != 0 ) { | ||
47 | name_and_error(destination); | ||
48 | return 1; | ||
49 | } | ||
50 | else | ||
51 | return 0; | ||
52 | } | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c new file mode 100644 index 000000000..2566beea0 --- /dev/null +++ b/coreutils/ls.c | |||
@@ -0,0 +1,542 @@ | |||
1 | #include "internal.h" | ||
2 | /* | ||
3 | * tiny-ls.c version 0.1.0: A minimalist 'ls' | ||
4 | * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * To achieve a small memory footprint, this version of 'ls' doesn't do any | ||
23 | * file sorting, and only has the most essential command line switches | ||
24 | * (i.e. the ones I couldn't live without :-) All features which involve | ||
25 | * linking in substantial chunks of libc can be disabled. | ||
26 | * | ||
27 | * Although I don't really want to add new features to this program to | ||
28 | * keep it small, I *am* interested to receive bug fixes and ways to make | ||
29 | * it more portable. | ||
30 | * | ||
31 | * KNOWN BUGS: | ||
32 | * 1. messy output if you mix files and directories on the command line | ||
33 | * 2. ls -l of a directory doesn't give "total <blocks>" header | ||
34 | * 3. ls of a symlink to a directory doesn't list directory contents | ||
35 | * 4. hidden files can make column width too large | ||
36 | * NON-OPTIMAL BEHAVIOUR: | ||
37 | * 1. autowidth reads directories twice | ||
38 | * 2. if you do a short directory listing without filetype characters | ||
39 | * appended, there's no need to stat each one | ||
40 | * PORTABILITY: | ||
41 | * 1. requires lstat (BSD) - how do you do it without? | ||
42 | */ | ||
43 | |||
44 | #define FEATURE_USERNAME /* show username/groupnames (libc6 uses NSS) */ | ||
45 | #define FEATURE_TIMESTAMPS /* show file timestamps */ | ||
46 | #define FEATURE_AUTOWIDTH /* calculate terminal & column widths */ | ||
47 | #define FEATURE_FILETYPECHAR /* enable -p and -F */ | ||
48 | |||
49 | #undef OP_BUF_SIZE 1024 /* leave undefined for unbuffered output */ | ||
50 | |||
51 | #define TERMINAL_WIDTH 80 /* use 79 if your terminal has linefold bug */ | ||
52 | #define COLUMN_WIDTH 14 /* default if AUTOWIDTH not defined */ | ||
53 | #define COLUMN_GAP 2 /* includes the file type char, if present */ | ||
54 | |||
55 | /************************************************************************/ | ||
56 | |||
57 | #define HAS_REWINDDIR | ||
58 | |||
59 | #if 1 /* FIXME libc 6 */ | ||
60 | # include <linux/types.h> | ||
61 | #else | ||
62 | # include <sys/types.h> | ||
63 | #endif | ||
64 | #include <sys/stat.h> | ||
65 | #include <stdio.h> | ||
66 | #include <unistd.h> | ||
67 | #include <dirent.h> | ||
68 | #include <errno.h> | ||
69 | #include <stdio.h> | ||
70 | #ifdef FEATURE_USERNAME | ||
71 | #include <pwd.h> | ||
72 | #include <grp.h> | ||
73 | #endif | ||
74 | #ifdef FEATURE_TIMESTAMPS | ||
75 | #include <time.h> | ||
76 | #endif | ||
77 | |||
78 | #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) | ||
79 | #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) | ||
80 | #ifdef FEATURE_FILETYPECHAR | ||
81 | #define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) | ||
82 | #endif | ||
83 | |||
84 | #ifndef MAJOR | ||
85 | #define MAJOR(dev) (((dev)>>8)&0xff) | ||
86 | #define MINOR(dev) ((dev)&0xff) | ||
87 | #endif | ||
88 | |||
89 | #define MODE1 "rwxrwxrwx" | ||
90 | #define MODE0 "---------" | ||
91 | #define SMODE1 "..s..s..t" | ||
92 | #define SMODE0 "..S..S..T" | ||
93 | |||
94 | /* The 9 mode bits to test */ | ||
95 | |||
96 | static const umode_t MBIT[] = { | ||
97 | S_IRUSR, S_IWUSR, S_IXUSR, | ||
98 | S_IRGRP, S_IWGRP, S_IXGRP, | ||
99 | S_IROTH, S_IWOTH, S_IXOTH | ||
100 | }; | ||
101 | |||
102 | /* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ | ||
103 | |||
104 | static const umode_t SBIT[] = { | ||
105 | 0, 0, S_ISUID, | ||
106 | 0, 0, S_ISGID, | ||
107 | 0, 0, S_ISVTX | ||
108 | }; | ||
109 | |||
110 | #define FMT_AUTO 0 | ||
111 | #define FMT_LONG 1 /* one record per line, extended info */ | ||
112 | #define FMT_SINGLE 2 /* one record per line */ | ||
113 | #define FMT_ROWS 3 /* print across rows */ | ||
114 | #define FMT_COLUMNS 3 /* fill columns (same, since we don't sort) */ | ||
115 | |||
116 | #define TIME_MOD 0 | ||
117 | #define TIME_CHANGE 1 | ||
118 | #define TIME_ACCESS 2 | ||
119 | |||
120 | #define DISP_FTYPE 1 /* show character for file type */ | ||
121 | #define DISP_EXEC 2 /* show '*' if regular executable file */ | ||
122 | #define DISP_HIDDEN 4 /* show files starting . (except . and ..) */ | ||
123 | #define DISP_DOT 8 /* show . and .. */ | ||
124 | #define DISP_NUMERIC 16 /* numeric uid and gid */ | ||
125 | #define DISP_FULLTIME 32 /* show extended time display */ | ||
126 | #define DIR_NOLIST 64 /* show directory as itself, not contents */ | ||
127 | #define DISP_DIRNAME 128 /* show directory name (for internal use) */ | ||
128 | #define DIR_RECURSE 256 /* -R (not yet implemented) */ | ||
129 | |||
130 | static unsigned char display_fmt = FMT_AUTO; | ||
131 | static unsigned short opts = 0; | ||
132 | static unsigned short column = 0; | ||
133 | |||
134 | #ifdef FEATURE_AUTOWIDTH | ||
135 | static unsigned short terminal_width = 0, column_width = 0; | ||
136 | #else | ||
137 | #define terminal_width TERMINAL_WIDTH | ||
138 | #define column_width COLUMN_WIDTH | ||
139 | #endif | ||
140 | |||
141 | #ifdef FEATURE_TIMESTAMPS | ||
142 | static unsigned char time_fmt = TIME_MOD; | ||
143 | #endif | ||
144 | |||
145 | #define wr(data,len) fwrite(data, 1, len, stdout) | ||
146 | |||
147 | static void writenum(long val, short minwidth) | ||
148 | { | ||
149 | char scratch[20]; | ||
150 | |||
151 | char *p = scratch + sizeof(scratch); | ||
152 | short len = 0; | ||
153 | short neg = (val < 0); | ||
154 | |||
155 | if (neg) val = -val; | ||
156 | do | ||
157 | *--p = (val % 10) + '0', len++, val /= 10; | ||
158 | while (val); | ||
159 | if (neg) | ||
160 | *--p = '-', len++; | ||
161 | while (len < minwidth) | ||
162 | *--p = ' ', len++; | ||
163 | wr(p, len); | ||
164 | column += len; | ||
165 | } | ||
166 | |||
167 | static void newline(void) | ||
168 | { | ||
169 | if (column > 0) { | ||
170 | wr("\n", 1); | ||
171 | column = 0; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | static void tab(short col) | ||
176 | { | ||
177 | static const char spaces[] = " "; | ||
178 | #define nspaces ((sizeof spaces)-1) /* null terminator! */ | ||
179 | |||
180 | short n = col - column; | ||
181 | |||
182 | if (n > 0) { | ||
183 | column = col; | ||
184 | while (n > nspaces) { | ||
185 | wr(spaces, nspaces); | ||
186 | n -= nspaces; | ||
187 | } | ||
188 | /* must be 1...(sizeof spaces) left */ | ||
189 | wr(spaces, n); | ||
190 | } | ||
191 | #undef nspaces | ||
192 | } | ||
193 | |||
194 | #ifdef FEATURE_FILETYPECHAR | ||
195 | static char append_char(umode_t mode) | ||
196 | { | ||
197 | if (!(opts & DISP_FTYPE)) | ||
198 | return '\0'; | ||
199 | if ((opts & DISP_EXEC) && S_ISREG(mode) && (mode & (S_IXUSR|S_IXGRP|S_IXOTH))) | ||
200 | return '*'; | ||
201 | return APPCHAR(mode); | ||
202 | } | ||
203 | #endif | ||
204 | |||
205 | /** | ||
206 | ** | ||
207 | ** Display a file or directory as a single item | ||
208 | ** (in either long or short format) | ||
209 | ** | ||
210 | **/ | ||
211 | |||
212 | static void list_single(const char *name, struct stat *info) | ||
213 | { | ||
214 | char scratch[20]; | ||
215 | short len = strlen(name); | ||
216 | #ifdef FEATURE_FILETYPECHAR | ||
217 | char append = append_char(info->st_mode); | ||
218 | #endif | ||
219 | |||
220 | if (display_fmt == FMT_LONG) { | ||
221 | umode_t mode = info->st_mode; | ||
222 | int i; | ||
223 | |||
224 | scratch[0] = TYPECHAR(mode); | ||
225 | for (i=0; i<9; i++) | ||
226 | if (mode & SBIT[i]) | ||
227 | scratch[i+1] = (mode & MBIT[i]) | ||
228 | ? SMODE1[i] | ||
229 | : SMODE0[i]; | ||
230 | else | ||
231 | scratch[i+1] = (mode & MBIT[i]) | ||
232 | ? MODE1[i] | ||
233 | : MODE0[i]; | ||
234 | newline(); | ||
235 | wr(scratch, 10); | ||
236 | column=10; | ||
237 | writenum((long)info->st_nlink,(short)4); | ||
238 | fputs(" ", stdout); | ||
239 | #ifdef FEATURE_USERNAME | ||
240 | if (!(opts & DISP_NUMERIC)) { | ||
241 | struct passwd *pw = getpwuid(info->st_uid); | ||
242 | if (pw) | ||
243 | fputs(pw->pw_name, stdout); | ||
244 | else | ||
245 | writenum((long)info->st_uid,(short)0); | ||
246 | } else | ||
247 | #endif | ||
248 | writenum((long)info->st_uid,(short)0); | ||
249 | tab(24); | ||
250 | #ifdef FEATURE_USERNAME | ||
251 | if (!(opts & DISP_NUMERIC)) { | ||
252 | struct group *gr = getgrgid(info->st_gid); | ||
253 | if (gr) | ||
254 | fputs(gr->gr_name, stdout); | ||
255 | else | ||
256 | writenum((long)info->st_gid,(short)0); | ||
257 | } else | ||
258 | #endif | ||
259 | writenum((long)info->st_gid,(short)0); | ||
260 | tab(33); | ||
261 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | ||
262 | writenum((long)MAJOR(info->st_rdev),(short)3); | ||
263 | fputs(", ", stdout); | ||
264 | writenum((long)MINOR(info->st_rdev),(short)3); | ||
265 | } | ||
266 | else | ||
267 | writenum((long)info->st_size,(short)8); | ||
268 | fputs(" ", stdout); | ||
269 | #ifdef FEATURE_TIMESTAMPS | ||
270 | { | ||
271 | time_t cal; | ||
272 | char *string; | ||
273 | |||
274 | switch(time_fmt) { | ||
275 | case TIME_CHANGE: | ||
276 | cal=info->st_ctime; break; | ||
277 | case TIME_ACCESS: | ||
278 | cal=info->st_atime; break; | ||
279 | default: | ||
280 | cal=info->st_mtime; break; | ||
281 | } | ||
282 | string=ctime(&cal); | ||
283 | if (opts & DISP_FULLTIME) | ||
284 | wr(string,24); | ||
285 | else { | ||
286 | time_t age = time(NULL) - cal; | ||
287 | wr(string+4,7); /* mmm_dd_ */ | ||
288 | if(age < 3600L*24*365/2 && age > -15*60) | ||
289 | /* hh:mm if less than 6 months old */ | ||
290 | wr(string+11,5); | ||
291 | else | ||
292 | /* _yyyy otherwise */ | ||
293 | wr(string+19,5); | ||
294 | } | ||
295 | wr(" ", 1); | ||
296 | } | ||
297 | #else | ||
298 | fputs("--- -- ----- ", stdout); | ||
299 | #endif | ||
300 | wr(name, len); | ||
301 | if (S_ISLNK(mode)) { | ||
302 | wr(" -> ", 4); | ||
303 | len = readlink(name, scratch, sizeof scratch); | ||
304 | if (len > 0) fwrite(scratch, 1, len, stdout); | ||
305 | #ifdef FEATURE_FILETYPECHAR | ||
306 | /* show type of destination */ | ||
307 | if (opts & DISP_FTYPE) { | ||
308 | if (!stat(name, info)) { | ||
309 | append = append_char(info->st_mode); | ||
310 | if (append) | ||
311 | fputc(append, stdout); | ||
312 | } | ||
313 | } | ||
314 | #endif | ||
315 | } | ||
316 | #ifdef FEATURE_FILETYPECHAR | ||
317 | else if (append) | ||
318 | wr(&append, 1); | ||
319 | #endif | ||
320 | } else { | ||
321 | static short nexttab = 0; | ||
322 | |||
323 | /* sort out column alignment */ | ||
324 | if (column == 0) | ||
325 | ; /* nothing to do */ | ||
326 | else if (display_fmt == FMT_SINGLE) | ||
327 | newline(); | ||
328 | else { | ||
329 | if (nexttab + column_width > terminal_width | ||
330 | #ifndef FEATURE_AUTOWIDTH | ||
331 | || nexttab + len >= terminal_width | ||
332 | #endif | ||
333 | ) | ||
334 | newline(); | ||
335 | else | ||
336 | tab(nexttab); | ||
337 | } | ||
338 | /* work out where next column starts */ | ||
339 | #ifdef FEATURE_AUTOWIDTH | ||
340 | /* we know the calculated width is big enough */ | ||
341 | nexttab = column + column_width + COLUMN_GAP; | ||
342 | #else | ||
343 | /* might cover more than one fixed-width column */ | ||
344 | nexttab = column; | ||
345 | do | ||
346 | nexttab += column_width + COLUMN_GAP; | ||
347 | while (nexttab < (column + len + COLUMN_GAP)); | ||
348 | #endif | ||
349 | /* now write the data */ | ||
350 | wr(name, len); | ||
351 | column = column + len; | ||
352 | #ifdef FEATURE_FILETYPECHAR | ||
353 | if (append) | ||
354 | wr(&append, 1), column++; | ||
355 | #endif | ||
356 | } | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | ** | ||
361 | ** List the given file or directory, expanding a directory | ||
362 | ** to show its contents if required | ||
363 | ** | ||
364 | **/ | ||
365 | |||
366 | static int list_item(const char *name) | ||
367 | { | ||
368 | struct stat info; | ||
369 | DIR *dir; | ||
370 | struct dirent *entry; | ||
371 | char fullname[MAXNAMLEN+1], *fnend; | ||
372 | |||
373 | if (lstat(name, &info)) | ||
374 | goto listerr; | ||
375 | |||
376 | if (!S_ISDIR(info.st_mode) || | ||
377 | (opts & DIR_NOLIST)) { | ||
378 | list_single(name, &info); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* Otherwise, it's a directory we want to list the contents of */ | ||
383 | |||
384 | if (opts & DISP_DIRNAME) { /* identify the directory */ | ||
385 | if (column) | ||
386 | wr("\n\n", 2), column = 0; | ||
387 | wr(name, strlen(name)); | ||
388 | wr(":\n", 2); | ||
389 | } | ||
390 | |||
391 | dir = opendir(name); | ||
392 | if (!dir) goto listerr; | ||
393 | #ifdef FEATURE_AUTOWIDTH | ||
394 | column_width = 0; | ||
395 | while ((entry = readdir(dir)) != NULL) { | ||
396 | short w = strlen(entry->d_name); | ||
397 | if (column_width < w) | ||
398 | column_width = w; | ||
399 | } | ||
400 | #ifdef HAS_REWINDDIR | ||
401 | rewinddir(dir); | ||
402 | #else | ||
403 | closedir(dir); | ||
404 | dir = opendir(name); | ||
405 | if (!dir) goto listerr; | ||
406 | #endif | ||
407 | #endif | ||
408 | |||
409 | /* List the contents */ | ||
410 | |||
411 | strcpy(fullname,name); /* *** ignore '.' by itself */ | ||
412 | fnend=fullname+strlen(fullname); | ||
413 | if (fnend[-1] != '/') | ||
414 | *fnend++ = '/'; | ||
415 | |||
416 | while ((entry = readdir(dir)) != NULL) { | ||
417 | const char *en=entry->d_name; | ||
418 | if (en[0] == '.') { | ||
419 | if (!en[1] || (en[1] == '.' && !en[2])) { /* . or .. */ | ||
420 | if (!(opts & DISP_DOT)) | ||
421 | continue; | ||
422 | } | ||
423 | else if (!(opts & DISP_HIDDEN)) | ||
424 | continue; | ||
425 | } | ||
426 | /* FIXME: avoid stat if not required */ | ||
427 | strcpy(fnend, entry->d_name); | ||
428 | if (lstat(fullname, &info)) | ||
429 | goto direrr; /* (shouldn't fail) */ | ||
430 | list_single(entry->d_name, &info); | ||
431 | } | ||
432 | closedir(dir); | ||
433 | return 0; | ||
434 | |||
435 | direrr: | ||
436 | closedir(dir); | ||
437 | listerr: | ||
438 | newline(); | ||
439 | name_and_error(name); | ||
440 | return 1; | ||
441 | } | ||
442 | |||
443 | const char ls_usage[] = "Usage: ls [-1a" | ||
444 | #ifdef FEATURE_TIMESTAMPS | ||
445 | "c" | ||
446 | #endif | ||
447 | "d" | ||
448 | #ifdef FEATURE_TIMESTAMPS | ||
449 | "e" | ||
450 | #endif | ||
451 | "ln" | ||
452 | #ifdef FEATURE_FILETYPECHAR | ||
453 | "p" | ||
454 | #endif | ||
455 | #ifdef FEATURE_TIMESTAMPS | ||
456 | "u" | ||
457 | #endif | ||
458 | "xAC" | ||
459 | #ifdef FEATURE_FILETYPECHAR | ||
460 | "F" | ||
461 | #endif | ||
462 | #ifdef FEATURE_RECURSIVE | ||
463 | "R" | ||
464 | #endif | ||
465 | "] [filenames...]\n"; | ||
466 | |||
467 | extern int | ||
468 | ls_main(struct FileInfo * not_used, int argc, char * * argv) | ||
469 | { | ||
470 | int argi=1, i; | ||
471 | |||
472 | /* process options */ | ||
473 | while (argi < argc && argv[argi][0] == '-') { | ||
474 | const char *p = &argv[argi][1]; | ||
475 | |||
476 | if (!*p) goto print_usage_message; /* "-" by itself not allowed */ | ||
477 | if (*p == '-') { | ||
478 | if (!p[1]) { /* "--" forces end of options */ | ||
479 | argi++; | ||
480 | break; | ||
481 | } | ||
482 | /* it's a long option name - we don't support them */ | ||
483 | goto print_usage_message; | ||
484 | } | ||
485 | |||
486 | while (*p) | ||
487 | switch (*p++) { | ||
488 | case 'l': display_fmt = FMT_LONG; break; | ||
489 | case '1': display_fmt = FMT_SINGLE; break; | ||
490 | case 'x': display_fmt = FMT_ROWS; break; | ||
491 | case 'C': display_fmt = FMT_COLUMNS; break; | ||
492 | #ifdef FEATURE_FILETYPECHAR | ||
493 | case 'p': opts |= DISP_FTYPE; break; | ||
494 | case 'F': opts |= DISP_FTYPE|DISP_EXEC; break; | ||
495 | #endif | ||
496 | case 'A': opts |= DISP_HIDDEN; break; | ||
497 | case 'a': opts |= DISP_HIDDEN|DISP_DOT; break; | ||
498 | case 'n': opts |= DISP_NUMERIC; break; | ||
499 | case 'd': opts |= DIR_NOLIST; break; | ||
500 | #ifdef FEATURE_RECURSIVE | ||
501 | case 'R': opts |= DIR_RECURSE; break; | ||
502 | #endif | ||
503 | #ifdef FEATURE_TIMESTAMPS | ||
504 | case 'u': time_fmt = TIME_ACCESS; break; | ||
505 | case 'c': time_fmt = TIME_CHANGE; break; | ||
506 | case 'e': opts |= DISP_FULLTIME; break; | ||
507 | #endif | ||
508 | default: goto print_usage_message; | ||
509 | } | ||
510 | |||
511 | argi++; | ||
512 | } | ||
513 | |||
514 | /* choose a display format */ | ||
515 | if (display_fmt == FMT_AUTO) | ||
516 | display_fmt = isatty(STDOUT_FILENO) ? FMT_COLUMNS : FMT_SINGLE; | ||
517 | if (argi < argc - 1) | ||
518 | opts |= DISP_DIRNAME; /* 2 or more items? label directories */ | ||
519 | #ifdef FEATURE_AUTOWIDTH | ||
520 | /* could add a -w option and/or TIOCGWINSZ call */ | ||
521 | if (terminal_width < 1) terminal_width = TERMINAL_WIDTH; | ||
522 | |||
523 | for (i = argi; i < argc; i++) { | ||
524 | int len = strlen(argv[i]); | ||
525 | if (column_width < len) | ||
526 | column_width = len; | ||
527 | } | ||
528 | #endif | ||
529 | |||
530 | /* process files specified, or current directory if none */ | ||
531 | i=0; | ||
532 | if (argi == argc) | ||
533 | i = list_item("."); | ||
534 | while (argi < argc) | ||
535 | i |= list_item(argv[argi++]); | ||
536 | newline(); | ||
537 | return i; | ||
538 | |||
539 | print_usage_message: | ||
540 | usage(ls_usage); | ||
541 | return 1; | ||
542 | } | ||
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c new file mode 100644 index 000000000..8f1fa04db --- /dev/null +++ b/coreutils/mkdir.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include "internal.h" | ||
2 | #include <errno.h> | ||
3 | #include <sys/param.h> | ||
4 | |||
5 | const char mkdir_usage[] = "mkdir [-m mode] directory [directory ...]\n" | ||
6 | "\tCreate directories.\n" | ||
7 | "\n" | ||
8 | "\t-m mode:\tSpecifiy the mode for the new directory\n" | ||
9 | "\t\tunder the argument directory."; | ||
10 | |||
11 | /*make directories skipping the last part of the path. Used here and by untar*/ | ||
12 | int mkdir_until(const char *fpath, const struct FileInfo * fi) | ||
13 | { | ||
14 | char path[PATH_MAX]; | ||
15 | char * s = path; | ||
16 | |||
17 | strcpy(path, fpath); | ||
18 | if ( s[0] == '\0' && s[1] == '\0' ) { | ||
19 | usage(mkdir_usage); | ||
20 | return 1; | ||
21 | } | ||
22 | s++; | ||
23 | while ( *s != '\0' ) { | ||
24 | if ( *s == '/' ) { | ||
25 | int status; | ||
26 | |||
27 | *s = '\0'; | ||
28 | status = mkdir(path, (fi?fi->orWithMode:0700) ); | ||
29 | *s = '/'; | ||
30 | |||
31 | if ( status != 0 ) { | ||
32 | if ( errno != EEXIST ) { | ||
33 | name_and_error(fpath); | ||
34 | return 1; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | } | ||
39 | s++; | ||
40 | } | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | int | ||
45 | mkdir_fn(const struct FileInfo * i) | ||
46 | { | ||
47 | if ( i->makeParentDirectories ) { | ||
48 | if(mkdir_until(i->source, i)) return 1; | ||
49 | } | ||
50 | |||
51 | if ( mkdir(i->source, i->orWithMode) != 0 && errno != EEXIST ) { | ||
52 | name_and_error(i->source); | ||
53 | return 1; | ||
54 | } | ||
55 | else | ||
56 | return 0; | ||
57 | } | ||
58 | |||
diff --git a/coreutils/mknod.c b/coreutils/mknod.c new file mode 100644 index 000000000..b18394bec --- /dev/null +++ b/coreutils/mknod.c | |||
@@ -0,0 +1,52 @@ | |||
1 | #include "internal.h" | ||
2 | #include <errno.h> | ||
3 | #include <sys/types.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <unistd.h> | ||
7 | |||
8 | const char mknod_usage[] = "mknod file b|c|u|p major minor\n" | ||
9 | "\tMake special files.\n" | ||
10 | "\n" | ||
11 | "\tb:\tMake a block (buffered) device.\n" | ||
12 | "\tc or u:\tMake a character (un-buffered) device.\n" | ||
13 | "\tp:\tMake a named pipe. Major and minor are ignored for named pipes.\n"; | ||
14 | |||
15 | int | ||
16 | mknod_main(struct FileInfo * i, int argc, char * * argv) | ||
17 | { | ||
18 | mode_t mode = 0; | ||
19 | dev_t dev = 0; | ||
20 | |||
21 | switch(argv[2][0]) { | ||
22 | case 'c': | ||
23 | case 'u': | ||
24 | mode = S_IFCHR; | ||
25 | break; | ||
26 | case 'b': | ||
27 | mode = S_IFBLK; | ||
28 | break; | ||
29 | case 'p': | ||
30 | mode = S_IFIFO; | ||
31 | break; | ||
32 | default: | ||
33 | usage(mknod_usage); | ||
34 | return 1; | ||
35 | } | ||
36 | |||
37 | if ( mode == S_IFCHR || mode == S_IFBLK ) { | ||
38 | dev = (atoi(argv[3]) << 8) | atoi(argv[4]); | ||
39 | if ( argc != 5 ) { | ||
40 | usage(mknod_usage); | ||
41 | return 1; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | mode |= 0666; | ||
46 | |||
47 | if ( mknod(argv[1], mode, dev) != 0 ) { | ||
48 | name_and_error(argv[1]); | ||
49 | return 1; | ||
50 | } | ||
51 | return 0; | ||
52 | } | ||
diff --git a/coreutils/mv.c b/coreutils/mv.c new file mode 100644 index 000000000..22c4a1207 --- /dev/null +++ b/coreutils/mv.c | |||
@@ -0,0 +1,38 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <errno.h> | ||
4 | |||
5 | const char mv_usage[] = "mv source-file destination-file\n" | ||
6 | "\t\tmv source-file [source-file ...] destination-directory\n" | ||
7 | "\n" | ||
8 | "\tMove the source files to the destination.\n" | ||
9 | "\n"; | ||
10 | |||
11 | extern int | ||
12 | mv_fn(const struct FileInfo * i) | ||
13 | { | ||
14 | struct stat destination_stat; | ||
15 | char d[1024]; | ||
16 | struct FileInfo n; | ||
17 | |||
18 | if ( stat(i->destination, &destination_stat) == 0 ) { | ||
19 | if ( i->stat.st_ino == destination_stat.st_ino | ||
20 | && i->stat.st_dev == destination_stat.st_dev ) | ||
21 | return 0; /* Move file to itself. */ | ||
22 | } | ||
23 | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { | ||
24 | n = *i; | ||
25 | n.destination = join_paths(d, i->destination, basename(i->source)); | ||
26 | i = &n; | ||
27 | } | ||
28 | if ( rename(i->source, i->destination) == 0 ) | ||
29 | return 0; | ||
30 | else if ( errno == EXDEV && is_a_directory(i->source) ) { | ||
31 | fprintf(stderr | ||
32 | ,"%s: Can't move directory across filesystems.\n" | ||
33 | ,i->source); | ||
34 | return 1; | ||
35 | } | ||
36 | else | ||
37 | return cp_fn(i); | ||
38 | } | ||
diff --git a/coreutils/printf.c b/coreutils/printf.c new file mode 100644 index 000000000..e79843c80 --- /dev/null +++ b/coreutils/printf.c | |||
@@ -0,0 +1,531 @@ | |||
1 | // I may still need some more cleaning...fix my error checking | ||
2 | |||
3 | #include "internal.h" | ||
4 | #ifdef BB_PRINTF | ||
5 | |||
6 | /* printf - format and print data | ||
7 | Copyright (C) 90, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2, or (at your option) | ||
12 | any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software Foundation, | ||
21 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
22 | |||
23 | /* Usage: printf format [argument...] | ||
24 | |||
25 | A front end to the printf function that lets it be used from the shell. | ||
26 | |||
27 | Backslash escapes: | ||
28 | |||
29 | \" = double quote | ||
30 | \\ = backslash | ||
31 | \a = alert (bell) | ||
32 | \b = backspace | ||
33 | \c = produce no further output | ||
34 | \f = form feed | ||
35 | \n = new line | ||
36 | \r = carriage return | ||
37 | \t = horizontal tab | ||
38 | \v = vertical tab | ||
39 | \0ooo = octal number (ooo is 0 to 3 digits) | ||
40 | \xhhh = hexadecimal number (hhh is 1 to 3 digits) | ||
41 | |||
42 | Additional directive: | ||
43 | |||
44 | %b = print an argument string, interpreting backslash escapes | ||
45 | |||
46 | The `format' argument is re-used as many times as necessary | ||
47 | to convert all of the given arguments. | ||
48 | |||
49 | David MacKenzie <djm@gnu.ai.mit.edu> */ | ||
50 | |||
51 | |||
52 | // 19990508 Busy Boxed! Dave Cinege | ||
53 | |||
54 | #include <unistd.h> | ||
55 | #include <stdio.h> | ||
56 | #include <sys/types.h> | ||
57 | #include <getopt.h> | ||
58 | #include <sys/stat.h> | ||
59 | #include <string.h> | ||
60 | #include <errno.h> | ||
61 | #include <stdlib.h> | ||
62 | #include <fcntl.h> | ||
63 | #include <ctype.h> | ||
64 | #include <libintl.h> | ||
65 | |||
66 | |||
67 | #ifndef S_IFMT | ||
68 | # define S_IFMT 0170000 | ||
69 | #endif | ||
70 | #if !defined(S_ISBLK) && defined(S_IFBLK) | ||
71 | # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) | ||
72 | #endif | ||
73 | #if !defined(S_ISCHR) && defined(S_IFCHR) | ||
74 | # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) | ||
75 | #endif | ||
76 | #if !defined(S_ISDIR) && defined(S_IFDIR) | ||
77 | # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | ||
78 | #endif | ||
79 | #if !defined(S_ISREG) && defined(S_IFREG) | ||
80 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | ||
81 | #endif | ||
82 | #if !defined(S_ISFIFO) && defined(S_IFIFO) | ||
83 | # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) | ||
84 | #endif | ||
85 | #if !defined(S_ISLNK) && defined(S_IFLNK) | ||
86 | # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) | ||
87 | #endif | ||
88 | #if !defined(S_ISSOCK) && defined(S_IFSOCK) | ||
89 | # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) | ||
90 | #endif | ||
91 | #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ | ||
92 | # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) | ||
93 | # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) | ||
94 | #endif | ||
95 | #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ | ||
96 | # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) | ||
97 | #endif | ||
98 | |||
99 | #define IN_CTYPE_DOMAIN(c) 1 | ||
100 | |||
101 | #ifdef isblank | ||
102 | # define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c)) | ||
103 | #else | ||
104 | # define ISBLANK(c) ((c) == ' ' || (c) == '\t') | ||
105 | #endif | ||
106 | #ifdef isgraph | ||
107 | # define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c)) | ||
108 | #else | ||
109 | # define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c)) | ||
110 | #endif | ||
111 | |||
112 | #define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) | ||
113 | #define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c)) | ||
114 | #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) | ||
115 | #define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c)) | ||
116 | #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c)) | ||
117 | #define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (c)) | ||
118 | #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) | ||
119 | #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) | ||
120 | #define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c)) | ||
121 | #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) | ||
122 | #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) | ||
123 | |||
124 | #define isodigit(c) ((c) >= '0' && (c) <= '7') | ||
125 | #define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)<='F' ? (c)-'A'+10 : (c)-'0') | ||
126 | #define octtobin(c) ((c) - '0') | ||
127 | |||
128 | char *xmalloc (); | ||
129 | |||
130 | static double xstrtod __P ((char *s)); | ||
131 | static int print_esc __P ((char *escstart)); | ||
132 | static int print_formatted __P ((char *format, int argc, char **argv)); | ||
133 | static long xstrtol __P ((char *s)); | ||
134 | static unsigned long xstrtoul __P ((char *s)); | ||
135 | static void print_direc __P ((char *start, size_t length, int field_width, int precision, char *argument)); | ||
136 | static void print_esc_char __P ((int c)); | ||
137 | static void print_esc_string __P ((char *str)); | ||
138 | static void verify __P ((char *s, char *end)); | ||
139 | |||
140 | /* The value to return to the calling program. */ | ||
141 | static int exit_status; | ||
142 | |||
143 | const char printf_usage[] = "Usage: printf format [argument...]\n"; | ||
144 | |||
145 | int | ||
146 | printf_main(struct FileInfo * i, int argc, char * * argv) | ||
147 | { | ||
148 | char *format; | ||
149 | int args_used; | ||
150 | |||
151 | exit_status = 0; | ||
152 | |||
153 | format = argv[1]; | ||
154 | argc -= 2; | ||
155 | argv += 2; | ||
156 | |||
157 | do | ||
158 | { | ||
159 | args_used = print_formatted (format, argc, argv); | ||
160 | argc -= args_used; | ||
161 | argv += args_used; | ||
162 | } | ||
163 | while (args_used > 0 && argc > 0); | ||
164 | |||
165 | /* | ||
166 | if (argc > 0) | ||
167 | fprintf(stderr, "excess args ignored"); | ||
168 | */ | ||
169 | |||
170 | exit (exit_status); | ||
171 | } | ||
172 | |||
173 | /* Print the text in FORMAT, using ARGV (with ARGC elements) for | ||
174 | arguments to any `%' directives. | ||
175 | Return the number of elements of ARGV used. */ | ||
176 | |||
177 | static int | ||
178 | print_formatted (char *format, int argc, char **argv) | ||
179 | { | ||
180 | int save_argc = argc; /* Preserve original value. */ | ||
181 | char *f; /* Pointer into `format'. */ | ||
182 | char *direc_start; /* Start of % directive. */ | ||
183 | size_t direc_length; /* Length of % directive. */ | ||
184 | int field_width; /* Arg to first '*', or -1 if none. */ | ||
185 | int precision; /* Arg to second '*', or -1 if none. */ | ||
186 | |||
187 | for (f = format; *f; ++f) | ||
188 | { | ||
189 | switch (*f) | ||
190 | { | ||
191 | case '%': | ||
192 | direc_start = f++; | ||
193 | direc_length = 1; | ||
194 | field_width = precision = -1; | ||
195 | if (*f == '%') | ||
196 | { | ||
197 | putchar ('%'); | ||
198 | break; | ||
199 | } | ||
200 | if (*f == 'b') | ||
201 | { | ||
202 | if (argc > 0) | ||
203 | { | ||
204 | print_esc_string (*argv); | ||
205 | ++argv; | ||
206 | --argc; | ||
207 | } | ||
208 | break; | ||
209 | } | ||
210 | if (strchr ("-+ #", *f)) | ||
211 | { | ||
212 | ++f; | ||
213 | ++direc_length; | ||
214 | } | ||
215 | if (*f == '*') | ||
216 | { | ||
217 | ++f; | ||
218 | ++direc_length; | ||
219 | if (argc > 0) | ||
220 | { | ||
221 | field_width = xstrtoul (*argv); | ||
222 | ++argv; | ||
223 | --argc; | ||
224 | } | ||
225 | else | ||
226 | field_width = 0; | ||
227 | } | ||
228 | else | ||
229 | while (ISDIGIT (*f)) | ||
230 | { | ||
231 | ++f; | ||
232 | ++direc_length; | ||
233 | } | ||
234 | if (*f == '.') | ||
235 | { | ||
236 | ++f; | ||
237 | ++direc_length; | ||
238 | if (*f == '*') | ||
239 | { | ||
240 | ++f; | ||
241 | ++direc_length; | ||
242 | if (argc > 0) | ||
243 | { | ||
244 | precision = xstrtoul (*argv); | ||
245 | ++argv; | ||
246 | --argc; | ||
247 | } | ||
248 | else | ||
249 | precision = 0; | ||
250 | } | ||
251 | else | ||
252 | while (ISDIGIT (*f)) | ||
253 | { | ||
254 | ++f; | ||
255 | ++direc_length; | ||
256 | } | ||
257 | } | ||
258 | if (*f == 'l' || *f == 'L' || *f == 'h') | ||
259 | { | ||
260 | ++f; | ||
261 | ++direc_length; | ||
262 | } | ||
263 | /* | ||
264 | if (!strchr ("diouxXfeEgGcs", *f)) | ||
265 | fprintf(stderr, "%%%c: invalid directive", *f); | ||
266 | */ | ||
267 | ++direc_length; | ||
268 | if (argc > 0) | ||
269 | { | ||
270 | print_direc (direc_start, direc_length, field_width, | ||
271 | precision, *argv); | ||
272 | ++argv; | ||
273 | --argc; | ||
274 | } | ||
275 | else | ||
276 | print_direc (direc_start, direc_length, field_width, | ||
277 | precision, ""); | ||
278 | break; | ||
279 | |||
280 | case '\\': | ||
281 | f += print_esc (f); | ||
282 | break; | ||
283 | |||
284 | default: | ||
285 | putchar (*f); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return save_argc - argc; | ||
290 | } | ||
291 | |||
292 | /* Print a \ escape sequence starting at ESCSTART. | ||
293 | Return the number of characters in the escape sequence | ||
294 | besides the backslash. */ | ||
295 | |||
296 | static int | ||
297 | print_esc (char *escstart) | ||
298 | { | ||
299 | register char *p = escstart + 1; | ||
300 | int esc_value = 0; /* Value of \nnn escape. */ | ||
301 | int esc_length; /* Length of \nnn escape. */ | ||
302 | |||
303 | /* \0ooo and \xhhh escapes have maximum length of 3 chars. */ | ||
304 | if (*p == 'x') | ||
305 | { | ||
306 | for (esc_length = 0, ++p; | ||
307 | esc_length < 3 && ISXDIGIT (*p); | ||
308 | ++esc_length, ++p) | ||
309 | esc_value = esc_value * 16 + hextobin (*p); | ||
310 | /* if (esc_length == 0) | ||
311 | fprintf(stderr, "missing hex in esc"); | ||
312 | */ | ||
313 | putchar (esc_value); | ||
314 | } | ||
315 | else if (*p == '0') | ||
316 | { | ||
317 | for (esc_length = 0, ++p; | ||
318 | esc_length < 3 && isodigit (*p); | ||
319 | ++esc_length, ++p) | ||
320 | esc_value = esc_value * 8 + octtobin (*p); | ||
321 | putchar (esc_value); | ||
322 | } | ||
323 | else if (strchr ("\"\\abcfnrtv", *p)) | ||
324 | print_esc_char (*p++); | ||
325 | /* else | ||
326 | fprintf(stderr, "\\%c: invalid esc", *p); | ||
327 | */ | ||
328 | return p - escstart - 1; | ||
329 | } | ||
330 | |||
331 | /* Output a single-character \ escape. */ | ||
332 | |||
333 | static void | ||
334 | print_esc_char (int c) | ||
335 | { | ||
336 | switch (c) | ||
337 | { | ||
338 | case 'a': /* Alert. */ | ||
339 | putchar (7); | ||
340 | break; | ||
341 | case 'b': /* Backspace. */ | ||
342 | putchar (8); | ||
343 | break; | ||
344 | case 'c': /* Cancel the rest of the output. */ | ||
345 | exit (0); | ||
346 | break; | ||
347 | case 'f': /* Form feed. */ | ||
348 | putchar (12); | ||
349 | break; | ||
350 | case 'n': /* New line. */ | ||
351 | putchar (10); | ||
352 | break; | ||
353 | case 'r': /* Carriage return. */ | ||
354 | putchar (13); | ||
355 | break; | ||
356 | case 't': /* Horizontal tab. */ | ||
357 | putchar (9); | ||
358 | break; | ||
359 | case 'v': /* Vertical tab. */ | ||
360 | putchar (11); | ||
361 | break; | ||
362 | default: | ||
363 | putchar (c); | ||
364 | break; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | /* Print string STR, evaluating \ escapes. */ | ||
369 | |||
370 | static void | ||
371 | print_esc_string (char *str) | ||
372 | { | ||
373 | for (; *str; str++) | ||
374 | if (*str == '\\') | ||
375 | str += print_esc (str); | ||
376 | else | ||
377 | putchar (*str); | ||
378 | } | ||
379 | |||
380 | static void | ||
381 | print_direc (char *start, size_t length, int field_width, int precision, char *argument) | ||
382 | { | ||
383 | char *p; /* Null-terminated copy of % directive. */ | ||
384 | |||
385 | p = xmalloc ((unsigned) (length + 1)); | ||
386 | strncpy (p, start, length); | ||
387 | p[length] = 0; | ||
388 | |||
389 | switch (p[length - 1]) | ||
390 | { | ||
391 | case 'd': | ||
392 | case 'i': | ||
393 | if (field_width < 0) | ||
394 | { | ||
395 | if (precision < 0) | ||
396 | printf (p, xstrtol (argument)); | ||
397 | else | ||
398 | printf (p, precision, xstrtol (argument)); | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | if (precision < 0) | ||
403 | printf (p, field_width, xstrtol (argument)); | ||
404 | else | ||
405 | printf (p, field_width, precision, xstrtol (argument)); | ||
406 | } | ||
407 | break; | ||
408 | |||
409 | case 'o': | ||
410 | case 'u': | ||
411 | case 'x': | ||
412 | case 'X': | ||
413 | if (field_width < 0) | ||
414 | { | ||
415 | if (precision < 0) | ||
416 | printf (p, xstrtoul (argument)); | ||
417 | else | ||
418 | printf (p, precision, xstrtoul (argument)); | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | if (precision < 0) | ||
423 | printf (p, field_width, xstrtoul (argument)); | ||
424 | else | ||
425 | printf (p, field_width, precision, xstrtoul (argument)); | ||
426 | } | ||
427 | break; | ||
428 | |||
429 | case 'f': | ||
430 | case 'e': | ||
431 | case 'E': | ||
432 | case 'g': | ||
433 | case 'G': | ||
434 | if (field_width < 0) | ||
435 | { | ||
436 | if (precision < 0) | ||
437 | printf (p, xstrtod (argument)); | ||
438 | else | ||
439 | printf (p, precision, xstrtod (argument)); | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | if (precision < 0) | ||
444 | printf (p, field_width, xstrtod (argument)); | ||
445 | else | ||
446 | printf (p, field_width, precision, xstrtod (argument)); | ||
447 | } | ||
448 | break; | ||
449 | |||
450 | case 'c': | ||
451 | printf (p, *argument); | ||
452 | break; | ||
453 | |||
454 | case 's': | ||
455 | if (field_width < 0) | ||
456 | { | ||
457 | if (precision < 0) | ||
458 | printf (p, argument); | ||
459 | else | ||
460 | printf (p, precision, argument); | ||
461 | } | ||
462 | else | ||
463 | { | ||
464 | if (precision < 0) | ||
465 | printf (p, field_width, argument); | ||
466 | else | ||
467 | printf (p, field_width, precision, argument); | ||
468 | } | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | free (p); | ||
473 | } | ||
474 | |||
475 | static unsigned long | ||
476 | xstrtoul (char *s) | ||
477 | { | ||
478 | char *end; | ||
479 | unsigned long val; | ||
480 | |||
481 | errno = 0; | ||
482 | val = strtoul (s, &end, 0); | ||
483 | verify (s, end); | ||
484 | return val; | ||
485 | } | ||
486 | |||
487 | static long | ||
488 | xstrtol (char *s) | ||
489 | { | ||
490 | char *end; | ||
491 | long val; | ||
492 | |||
493 | errno = 0; | ||
494 | val = strtol (s, &end, 0); | ||
495 | verify (s, end); | ||
496 | return val; | ||
497 | } | ||
498 | |||
499 | static double | ||
500 | xstrtod (char *s) | ||
501 | { | ||
502 | char *end; | ||
503 | double val; | ||
504 | |||
505 | errno = 0; | ||
506 | val = strtod (s, &end); | ||
507 | verify (s, end); | ||
508 | return val; | ||
509 | } | ||
510 | |||
511 | static void | ||
512 | verify (char *s, char *end) | ||
513 | { | ||
514 | if (errno) | ||
515 | { | ||
516 | fprintf(stderr, "%s", s); | ||
517 | exit_status = 1; | ||
518 | } | ||
519 | else if (*end) | ||
520 | { | ||
521 | /* | ||
522 | if (s == end) | ||
523 | fprintf(stderr, "%s: expected numeric", s); | ||
524 | else | ||
525 | fprintf(stderr, "%s: not completely converted", s); | ||
526 | */ | ||
527 | exit_status = 1; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | #endif | ||
diff --git a/coreutils/pwd.c b/coreutils/pwd.c new file mode 100644 index 000000000..d9ab54e48 --- /dev/null +++ b/coreutils/pwd.c | |||
@@ -0,0 +1,18 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | |||
4 | const char pwd_usage[] = "Print the current directory.\n"; | ||
5 | |||
6 | extern int | ||
7 | pwd_main(struct FileInfo * i, int argc, char * * argv) | ||
8 | { | ||
9 | char buf[1024]; | ||
10 | |||
11 | if ( getcwd(buf, sizeof(buf)) == NULL ) { | ||
12 | name_and_error("get working directory"); | ||
13 | return 1; | ||
14 | } | ||
15 | |||
16 | printf("%s\n", buf); | ||
17 | return 0; | ||
18 | } | ||
diff --git a/coreutils/rm.c b/coreutils/rm.c new file mode 100644 index 000000000..dc35b0297 --- /dev/null +++ b/coreutils/rm.c | |||
@@ -0,0 +1,30 @@ | |||
1 | #include "internal.h" | ||
2 | #include <errno.h> | ||
3 | |||
4 | const char rm_usage[] = "rm [-r] file [file ...]\n" | ||
5 | "\n" | ||
6 | "\tDelete files.\n" | ||
7 | "\n" | ||
8 | "\t-r:\tRecursively remove files and directories.\n"; | ||
9 | |||
10 | extern int | ||
11 | rm_main(struct FileInfo * i, int argc, char * * argv) | ||
12 | { | ||
13 | i->processDirectoriesAfterTheirContents = 1; | ||
14 | return monadic_main(i, argc, argv); | ||
15 | } | ||
16 | |||
17 | extern int | ||
18 | rm_fn(const struct FileInfo * i) | ||
19 | { | ||
20 | if ( i->recursive | ||
21 | && !i->isSymbolicLink | ||
22 | && (i->stat.st_mode & S_IFMT) == S_IFDIR ) | ||
23 | return rmdir_fn(i); | ||
24 | else if ( unlink(i->source) != 0 && errno != ENOENT && !i->force ) { | ||
25 | name_and_error(i->source); | ||
26 | return 1; | ||
27 | } | ||
28 | else | ||
29 | return 0; | ||
30 | } | ||
diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c new file mode 100644 index 000000000..069e68546 --- /dev/null +++ b/coreutils/rmdir.c | |||
@@ -0,0 +1,17 @@ | |||
1 | #include "internal.h" | ||
2 | #include <errno.h> | ||
3 | |||
4 | const char rmdir_usage[] = "rmdir directory [directory ...]\n" | ||
5 | "\n" | ||
6 | "\tDelete directories.\n"; | ||
7 | |||
8 | extern int | ||
9 | rmdir_fn(const struct FileInfo * i) | ||
10 | { | ||
11 | if ( rmdir(i->source) != 0 && errno != ENOENT && !i->force ) { | ||
12 | name_and_error(i->source); | ||
13 | return 1; | ||
14 | } | ||
15 | else | ||
16 | return 0; | ||
17 | } | ||
diff --git a/coreutils/sleep.c b/coreutils/sleep.c new file mode 100644 index 000000000..e48e14b2f --- /dev/null +++ b/coreutils/sleep.c | |||
@@ -0,0 +1,15 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | |||
4 | const char sleep_usage[] = "sleep seconds\n" | ||
5 | "\n" | ||
6 | "\tPause program execution for the given number of seconds.\n"; | ||
7 | |||
8 | extern int | ||
9 | sleep_main(struct FileInfo * i, int argc, char * * argv) | ||
10 | { | ||
11 | if ( sleep(atoi(argv[1])) != 0 ) | ||
12 | return -1; | ||
13 | else | ||
14 | return 0; | ||
15 | } | ||
diff --git a/coreutils/sync.c b/coreutils/sync.c new file mode 100644 index 000000000..6fa5b380b --- /dev/null +++ b/coreutils/sync.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include "internal.h" | ||
2 | |||
3 | const char sync_usage[] = "sync\n" | ||
4 | "\n" | ||
5 | "\tWrite all buffered filesystem blocks to disk.\n"; | ||
6 | |||
7 | extern int | ||
8 | sync_main(struct FileInfo * i, int argc, char * * argv) | ||
9 | { | ||
10 | return sync(); | ||
11 | } | ||
diff --git a/coreutils/touch.c b/coreutils/touch.c new file mode 100644 index 000000000..ca4b98108 --- /dev/null +++ b/coreutils/touch.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include "internal.h" | ||
2 | #include <sys/types.h> | ||
3 | #include <stdio.h> | ||
4 | #include <utime.h> | ||
5 | |||
6 | const char touch_usage[] = "touch [-c] file [file ...]\n" | ||
7 | "\n" | ||
8 | "\tUpdate the last-modified date on the given file[s].\n"; | ||
9 | |||
10 | extern int | ||
11 | touch_fn(const struct FileInfo * i) | ||
12 | { | ||
13 | if ( (utime(i->source, 0) != 0) && (i->create != 1) ) { | ||
14 | if ( fopen(i->source, "w") == NULL ) { | ||
15 | name_and_error(i->source); | ||
16 | return 1; | ||
17 | } | ||
18 | } | ||
19 | return 0; | ||
20 | } | ||