e4484971e30bf738efb1101174052399d919cfd1
[src/app-framework-main.git] / src / main-wgtpkg-pack.c
1 /*
2  Copyright (C) 2015-2020 IoT.bzh
3
4  author: José Bollo <jose.bollo@iot.bzh>
5
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 #define _GNU_SOURCE
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <limits.h>
25 #include <errno.h>
26 #include <getopt.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29
30 #include "verbose.h"
31 #include "wgtpkg-files.h"
32 #include "wgtpkg-workdir.h"
33 #include "wgtpkg-zip.h"
34
35 const char appname[] = "wgtpkg-pack";
36
37 static void version()
38 {
39         printf(
40                 "\n"
41                 "  %s  version="AFM_VERSION"\n"
42                 "\n"
43                 "  Copyright (C) 2015-2020 \"IoT.bzh\"\n"
44                 "  AFB comes with ABSOLUTELY NO WARRANTY.\n"
45                 "  Licence Apache 2\n"
46                 "\n",
47                 appname
48         );
49 }
50
51 static void usage()
52 {
53         printf(
54                 "usage: %s [-f] [-o wgtfile] directory\n"
55                 "\n"
56                 "   -o wgtfile       the output widget file\n"
57                 "   -f               force overwriting\n"
58                 "   -q               quiet\n"
59                 "   -v               verbose\n"
60                 "   -V               version\n"
61                 "\n",
62                 appname
63         );
64 }
65
66 static struct option options[] = {
67         { "output",      required_argument, NULL, 'o' },
68         { "force",       no_argument,       NULL, 'f' },
69         { "help",        no_argument,       NULL, 'h' },
70         { "quiet",       no_argument,       NULL, 'q' },
71         { "verbose",     no_argument,       NULL, 'v' },
72         { "version",     no_argument,       NULL, 'V' },
73         { NULL, 0, NULL, 0 }
74 };
75
76 /* install the widgets of the list */
77 int main(int ac, char **av)
78 {
79         int i, force;
80         char *wgtfile, *directory, *x;
81         struct stat s;
82
83         LOGUSER(appname);
84
85         force = 0;
86         wgtfile = directory = NULL;
87         for (;;) {
88                 i = getopt_long(ac, av, "qvVhfo:", options, NULL);
89                 if (i < 0)
90                         break;
91                 switch (i) {
92                 case 'o':
93                         wgtfile = optarg;
94                         break;
95                 case 'q':
96                         if (verbosity)
97                                 verbosity--;
98                         break;
99                 case 'v':
100                         verbosity++;
101                         break;
102                 case 'f':
103                         force = 1;
104                         break;
105                 case 'h':
106                         usage();
107                         return 0;
108                 case 'V':
109                         version();
110                         return 0;
111                 case ':':
112                         ERROR("missing argument");
113                         return 1;
114                 default:
115                         ERROR("unrecognized option");
116                         return 1;
117                 }
118         }
119
120         /* remaining arguments and final checks */
121         if (optind >= ac) {
122                 ERROR("no directory set");
123                 return 1;
124         }
125         directory = av[optind++];
126         if (optind < ac) {
127                 ERROR("extra parameters found");
128                 return 1;
129         }
130
131         /* set default values */
132         if (wgtfile == NULL && 0 > asprintf(&wgtfile, "%s.wgt", directory)) {
133                 ERROR("asprintf failed");
134                 return 1;
135         }
136
137         /* check values */
138         if (stat(directory, &s)) {
139                 ERROR("can't find directory %s", directory);
140                 return 1;
141         }
142         if (!S_ISDIR(s.st_mode)) {
143                 ERROR("%s isn't a directory", directory);
144                 return 1;
145         }
146         if (access(wgtfile, F_OK) == 0 && force == 0) {
147                 ERROR("can't overwrite existing %s", wgtfile);
148                 return 1;
149         }
150
151         NOTICE("-- PACKING widget %s from directory %s", wgtfile, directory);
152
153         /* creates an existing widget (for realpath it must exist) */
154         i = open(wgtfile, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0644);
155         if (i < 0) {
156                 ERROR("can't write widget %s", wgtfile);
157                 return 1;
158         }
159         close(i);
160
161         /* compute absolutes paths */
162         x = realpath(wgtfile, NULL);
163         if (x == NULL) {
164                 ERROR("realpath failed for %s", wgtfile);
165                 return 1;
166         }
167         wgtfile = x;
168
169         /* set and enter the workdir */
170         if (chdir(directory)) {
171                 ERROR("failed to enter directory %s", directory);
172                 return 1;
173         }
174         if (set_workdir(".", 0))
175                 return 1;
176
177
178         if (fill_files())
179                 return 1;
180
181         return !!zwrite(wgtfile);
182 }
183
184