Mercurial > sci
annotate scictl/scictl.c @ 64:562372396019
misc: improve manual pages and documentation
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 18 Aug 2022 20:17:18 +0200 |
parents | 67470b67e460 |
children | 71cd8447e3a4 |
rev | line source |
---|---|
16
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
1 /* |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
2 * scictl.c -- main scictl(8) utility file |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
3 * |
32
081e1c258e64
misc: update copyright years
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
4 * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr> |
16
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
5 * |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
9 * |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
17 */ |
3051ef92173a
misc: add license headers
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
18 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
19 #include <errno.h> |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
20 #include <limits.h> |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
21 #include <stdint.h> |
0 | 22 #include <stdio.h> |
23 #include <stdlib.h> | |
24 #include <string.h> | |
25 #include <unistd.h> | |
26 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
27 #include <utlist.h> |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
28 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
29 #include "apic.h" |
0 | 30 #include "util.h" |
31 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
32 static void |
0 | 33 usage(void) |
34 { | |
52
95bc6b4ec753
sciworkerd: add API key support
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
35 fprintf(stderr, "usage: scictl [-k key] [-u baseurl] command [args...]\n"); |
0 | 36 exit(1); |
37 } | |
38 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
39 static void |
0 | 40 help(void) |
41 { | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
42 fprintf(stderr, "usage: scictl job-add project tag\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
43 fprintf(stderr, " scictl job-todo worker\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
44 fprintf(stderr, " scictl project-add name desc url script\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
45 fprintf(stderr, " scictl project-info name\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
46 fprintf(stderr, " scictl project-list\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
47 fprintf(stderr, " scictl project-update name key value\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
48 fprintf(stderr, " scictl worker-add name desc\n"); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
49 fprintf(stderr, " scictl worker-list\n"); |
0 | 50 exit(0); |
51 } | |
52 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
53 long long |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
54 toint(const char *s) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
55 { |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
56 long long v; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
57 const char *err; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
58 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
59 v = util_strtonum(s, 0, LLONG_MAX, &err); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
60 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
61 if (err) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
62 util_die("abort: %s\n", err); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
63 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
64 return v; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
65 } |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
66 |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
67 static char * |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
68 readfile(const char *path) |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
69 { |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
70 FILE *fp, *str; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
71 char buf[BUFSIZ], *console = NULL; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
72 size_t nr, consolesz = 0; |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
73 |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
74 if (strcmp(path, "-") == 0) |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
75 fp = stdin; |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
76 else if (!(fp = fopen(path, "r"))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
77 util_die("abort: %s: %s\n", path, strerror(errno)); |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
78 |
63
67470b67e460
misc: remove unneeded code
David Demelier <markand@malikania.fr>
parents:
61
diff
changeset
|
79 str = util_open_memstream(&console, &consolesz); |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
80 |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
81 while ((nr = fread(buf, 1, sizeof (buf), fp)) > 0) |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
82 fwrite(buf, 1, nr, str); |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
83 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
84 if ((ferror(fp) && !feof(fp)) || (ferror(str) && !feof(str))) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
85 util_die("abort: %s\n", strerror(errno)); |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
86 |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
87 fclose(str); |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
88 fclose(fp); |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
89 |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
90 return console; |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
91 } |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
92 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
93 static inline intmax_t |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
94 get_int(json_t *obj, const char *key) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
95 { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
96 json_t *val; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
97 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
98 if ((val = json_object_get(obj, key)) && json_is_integer(val)) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
99 return json_integer_value(val); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
100 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
101 return 0; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
102 } |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
103 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
104 static inline const char * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
105 get_string(json_t *obj, const char *key) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
106 { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
107 json_t *val; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
108 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
109 if ((val = json_object_get(obj, key)) && json_is_string(val)) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
110 return json_string_value(val); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
111 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
112 return ""; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
113 } |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
114 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
115 static void |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
116 cmd_job_add(int argc, char **argv) |
0 | 117 { |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
118 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
119 json_t *obj; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
120 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
121 if (argc < 3) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
122 usage(); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
123 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
124 obj = json_pack("{ss ss}", |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
125 "project_name", argv[1], |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
126 "tag", argv[2] |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
127 ); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
128 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
129 if (apic_job_add(&req, obj) < 0) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
130 util_die("abort: %s\n", req.error); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
131 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
132 json_decref(obj); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
133 } |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
134 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
135 static void |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
136 cmd_job_todo(int argc, char **argv) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
137 { |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
138 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
139 json_t *array, *obj; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
140 size_t i; |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
141 |
0 | 142 if (argc < 2) |
143 usage(); | |
144 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
145 if ((array = apic_job_todo(&req, argv[1]))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
146 util_die("abort: %s\n", req.error); |
1
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
147 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
148 json_array_foreach(array, i, obj) { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
149 printf("%-16s%jd\n", "id:", get_int(obj, "id")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
150 printf("%-16s%s\n", "tag:", get_string(obj, "tag")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
151 printf("%-16s%s\n", "project:", get_string(obj, "project_name")); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
152 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
153 if (i + 1 < json_array_size(array)) |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
154 printf("\n"); |
1
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
155 } |
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
156 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
157 json_decref(array); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
158 } |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
159 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
160 static void |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
161 cmd_project_add(int argc, char **argv) |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
162 { |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
163 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
164 char *script; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
165 json_t *obj; |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
166 |
1
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
167 if (argc < 5) |
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
168 usage(); |
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
169 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
170 script = readfile(argv[4]); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
171 obj = json_pack("{ss ss ss ss}", |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
172 "name", argv[1], |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
173 "desc", argv[2], |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
174 "url", argv[3], |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
175 "script", script |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
176 ); |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
177 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
178 if (apic_project_save(&req, obj) < 0) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
179 util_die("abort: unable to create project: %s\n", req.error); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
180 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
181 json_decref(obj); |
1
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
182 } |
5afdb14df924
sci: add support for storing results
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
183 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
184 static void |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
185 cmd_project_update(int argc, char **argv) |
0 | 186 { |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
187 struct apic req; |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
188 json_t *obj; |
0 | 189 |
190 if (argc < 4) | |
191 usage(); | |
192 | |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
193 if (!(obj = apic_project_find(&req, argv[1]))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
194 util_die("abort: unable to find project: %s\n", req.error); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
195 |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
196 /* Those fields are treated from argument. */ |
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
197 if (strcmp(argv[2], "name") == 0 || |
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
198 strcmp(argv[2], "desc") == 0 || |
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
199 strcmp(argv[2], "url") == 0) |
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
200 json_object_set_new(obj, argv[2], json_string(argv[3])); |
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
201 /* The script, however, is read from the file. */ |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
202 else if (strcmp(argv[2], "script") == 0) |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
203 json_object_set_new(obj, "script", json_string(readfile(argv[3]))); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
204 |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
205 if (apic_project_save(&req, obj) < 0) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
206 util_die("abort: unable to save project: %s\n", req.error); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
207 |
61
8be8188d61a5
scictl: resurrect project-update command
David Demelier <markand@malikania.fr>
parents:
53
diff
changeset
|
208 json_decref(obj); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
209 } |
0 | 210 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
211 static void |
13 | 212 cmd_project_info(int argc, char **argv) |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
213 { |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
214 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
215 json_t *obj; |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
216 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
217 if (argc < 2) |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
218 usage(); |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
219 if (!(obj = apic_project_find(&req, argv[1]))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
220 util_die("abort: unable to find project: %s\n", req.error); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
221 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
222 printf("%-16s%s\n", "name:", get_string(obj, "name")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
223 printf("%-16s%s\n", "desc:", get_string(obj, "desc")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
224 printf("%-16s%s\n", "url:", get_string(obj, "url")); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
225 printf("\n"); |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
226 printf("%s", get_string(obj, "script")); |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
227 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
228 json_decref(obj); |
0 | 229 } |
230 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
231 static void |
0 | 232 cmd_project_list(int argc, char **argv) |
233 { | |
234 (void)argc; | |
235 (void)argv; | |
236 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
237 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
238 json_t *array, *obj; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
239 size_t i; |
0 | 240 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
241 if (!(array = apic_project_list(&req))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
242 util_die("abort: unable to list projects: %s\n", req.error); |
0 | 243 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
244 json_array_foreach(array, i, obj) { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
245 printf("%-16s%s\n", "name:", get_string(obj, "name")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
246 printf("%-16s%s\n", "desc:", get_string(obj, "desc")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
247 printf("%-16s%s\n", "url:", get_string(obj, "url")); |
0 | 248 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
249 if (i + 1 < json_array_size(array)) |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
250 printf("\n"); |
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
251 } |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
252 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
253 json_decref(array); |
2
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
254 } |
5fa3d2f479b2
sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
1
diff
changeset
|
255 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
256 static void |
0 | 257 cmd_worker_add(int argc, char **argv) |
258 { | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
259 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
260 json_t *obj; |
0 | 261 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
262 if (argc < 3) |
0 | 263 usage(); |
264 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
265 obj = json_pack("{ss ss}", |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
266 "name", argv[1], |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
267 "desc", argv[2] |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
268 ); |
0 | 269 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
270 if (apic_worker_save(&req, obj) < 0) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
271 util_die("abort: unable to save worker: %s\n", req.error); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
272 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
273 json_decref(obj); |
0 | 274 } |
275 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
276 static void |
0 | 277 cmd_worker_list(int argc, char **argv) |
278 { | |
279 (void)argc; | |
280 (void)argv; | |
281 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
282 struct apic req; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
283 json_t *array, *obj; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
284 size_t i; |
0 | 285 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
286 if (!(array = apic_worker_list(&req))) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
287 util_die("abort: unable to list worker: %s\n", req.error); |
0 | 288 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
289 json_array_foreach(array, i, obj) { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
290 printf("%-16s%s\n", "name:", get_string(obj, "name")); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
291 printf("%-16s%s\n", "desc:", get_string(obj, "desc")); |
0 | 292 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
293 if (i + 1 < json_array_size(array)) |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
294 printf("\n"); |
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
295 } |
0 | 296 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
297 json_decref(array); |
0 | 298 } |
299 | |
300 static struct { | |
301 const char *name; | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
302 void (*exec)(int, char **); |
0 | 303 } commands[] = { |
3
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
304 { "job-add", cmd_job_add }, |
215c0c3b3609
misc: use JSON everywhere (scictl/sciwebd)
David Demelier <markand@malikania.fr>
parents:
2
diff
changeset
|
305 { "job-todo", cmd_job_todo }, |
0 | 306 { "project-add", cmd_project_add }, |
13 | 307 { "project-info", cmd_project_info }, |
0 | 308 { "project-list", cmd_project_list }, |
9
3ef8128e244f
sci: add project-update command
David Demelier <markand@malikania.fr>
parents:
4
diff
changeset
|
309 { "project-update", cmd_project_update }, |
0 | 310 { "worker-add", cmd_worker_add }, |
311 { "worker-list", cmd_worker_list }, | |
312 { NULL, NULL } | |
313 }; | |
314 | |
315 int | |
316 main(int argc, char **argv) | |
317 { | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
318 int ch; |
50
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
319 const char *env; |
0 | 320 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
321 opterr = 0; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
322 setenv("POSIXLY_CORRECT", "1", 1); |
0 | 323 |
50
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
324 /* Environment first, options after. */ |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
325 if ((env = getenv("SCI_API_URL"))) |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
326 util_strlcpy(apiconf.baseurl, env, sizeof (apiconf.baseurl)); |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
327 if ((env = getenv("SCI_API_KEY"))) |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
328 util_strlcpy(apiconf.key, env, sizeof (apiconf.key)); |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
329 |
53
319979427566
misc: refactor using util_getopt
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
330 while ((ch = util_getopt(argc, argv, "k:u:")) != -1) { |
0 | 331 switch (ch) { |
50
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
332 case 'k': |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
333 util_strlcpy(apiconf.key, optarg, sizeof (apiconf.key)); |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
334 break; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
335 case 'u': |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
336 util_strlcpy(apiconf.baseurl, optarg, sizeof (apiconf.baseurl)); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
337 break; |
0 | 338 default: |
339 break; | |
340 } | |
341 } | |
342 | |
343 argc -= optind; | |
344 argv += optind; | |
345 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
346 optind = 1; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
347 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
348 if (argc < 1) |
0 | 349 usage(); |
350 if (strcmp(argv[0], "help") == 0) | |
351 help(); | |
352 | |
50
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
353 /* At this step, every command requires an API key. */ |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
354 if (strlen(apiconf.key) == 0) |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
355 util_die("abort: no API key defined\n"); |
b474f0985e39
scictl: add API key support
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
356 |
0 | 357 for (size_t i = 0; commands[i].name; ++i) { |
358 if (strcmp(commands[i].name, argv[0]) == 0) { | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
359 commands[i].exec(argc, argv); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
360 return 0; |
0 | 361 } |
362 } | |
363 | |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
19
diff
changeset
|
364 util_die("abort: invalid command: %s\n", argv[0]); |
0 | 365 } |