latest and greatest.
[oweals/busybox.git] / monadic.c
1 #include "internal.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <grp.h>
5
6 extern int
7 monadic_main(
8  struct FileInfo *      i
9 ,int                            argc
10 ,char * *                       argv)
11 {
12         int     status = 0;
13
14         while ( argc > 1 && argv[1][0] == '-' ) {
15                 switch ( argv[1][1] ) {
16                 case 'c':
17                         i->create = 1;
18                         break;
19                 case 'f':
20                         i->force = 1;
21                         break;
22                 case 'g':
23                         if ( argc > 2 ) {
24                                 struct group *  g;
25                                 if ( (g = getgrnam(argv[2])) == 0 ) {
26                                         fprintf(stderr, "%s: no such group.\n", argv[1]);
27                                         return 1;
28                                 }
29                                 i->groupID = g->gr_gid;
30                                 i->changeGroupID = 1;
31                                 i->complainInPostProcess = 1;
32                                 argc--;
33                                 argv++;
34                                 break;
35                         }
36                         usage(i->applet->usage);
37                         return 1;
38                 case 'm':
39                         if ( argc > 2 ) {
40                                 status = parse_mode(
41                                  argv[2]
42                                 ,&i->orWithMode
43                                 ,&i->andWithMode, 0);
44
45                                 if ( status == 0 ) {
46                                         i->changeMode = 1;
47                                         i->complainInPostProcess = 1;
48                                         argc--;
49                                         argv++;
50                                         break;
51                                 }
52                         }
53                         usage(i->applet->usage);
54                         return 1;
55                 case 'o':
56                         if ( argc > 2 ) {
57                                 status = parse_user_name(argv[2], i);
58                                 if ( status != 0 )
59                                         return status;
60
61                                 i->changeUserID = 1;
62                                 i->complainInPostProcess = 1;
63                                 argc--;
64                                 argv++;
65                                 break;
66                         }
67                         usage(i->applet->usage);
68                         return 1;
69                 case 'p':
70                         i->makeParentDirectories = 1;
71                         break;
72                 case 'r':
73                 case 'R':
74                         i->recursive = 1;
75                         break;
76                 case 's':
77                         i->makeSymbolicLink = 1;
78                         break;
79                 default:
80                         usage(i->applet->usage);
81                         return 1;
82                 }
83                 argv++;
84                 argc--;
85         }
86         while ( argc > 1 ) {
87                 char *  slash;
88                 i->source = argv[1];
89                 if ( (slash = strrchr(i->source, '/')) != 0 ) {
90                         i->directoryLength = slash - i->source;
91                         if ( i->source[i->directoryLength] == '\0' )
92                                 i->directoryLength = 0;
93                 }
94                 else
95                         i->directoryLength = 0;
96                 if ( !i->dyadic )
97                         i->destination = i->source;
98
99                 if ( lstat(i->source, &i->stat) == 0 ) {
100                         i->isSymbolicLink = (i->stat.st_mode & S_IFMT)==S_IFLNK;
101                         if ( i->isSymbolicLink )
102                                 if ( stat(i->source, &i->stat) != 0 )
103                                         memset(&i->stat, 0, sizeof(i->stat));
104                 }
105                 else
106                         memset(&i->stat, 0, sizeof(i->stat));
107
108                 if ( i->isSymbolicLink
109                  || !i->recursive
110                  || ((i->stat.st_mode & S_IFMT) != S_IFDIR) ) {
111
112                         if ( i->applet->function )
113                                 status = i->applet->function(i);
114                         if ( status == 0 )
115                                 status = post_process(i);
116                 }
117                 else
118                         status = descend(i, i->applet->function);
119
120                 if ( status != 0 && !i->force )
121                         return status;
122                 argv++;
123                 argc--;
124         }
125         return 0;
126 }