Line data Source code
1 : /*
2 : cJSON_deploy.c
3 : Created by Danny Goossen, Gioxa Ltd on 11/2/17.
4 :
5 : MIT License
6 :
7 : Copyright (c) 2017 deployctl, Gioxa Ltd.
8 :
9 : Permission is hereby granted, free of charge, to any person obtaining a copy
10 : of this software and associated documentation files (the "Software"), to deal
11 : in the Software without restriction, including without limitation the rights
12 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 : copies of the Software, and to permit persons to whom the Software is
14 : furnished to do so, subject to the following conditions:
15 :
16 : The above copyright notice and this permission notice shall be included in all
17 : copies or substantial portions of the Software.
18 :
19 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 : SOFTWARE.
26 :
27 : */
28 :
29 : #include "deployd.h"
30 :
31 : // dupplicate a string from a non null terminated string
32 134 : char* cJSON_strdup_n(const unsigned char * str, size_t n)
33 : {
34 134 : size_t len = 0;
35 134 : char *copy = NULL;
36 :
37 134 : if (str == NULL)
38 : {
39 : return NULL;
40 : }
41 :
42 133 : len = n + 1;
43 133 : if (!(copy = (char *)calloc(len,1)))
44 : {
45 : return NULL;
46 : }
47 133 : memcpy(copy, str, len);
48 133 : copy[n]=0;
49 133 : return copy;
50 : }
51 :
52 : // add item to object with a key derived from a non 0 terminated string
53 69 : void cJSON_AddItemToObject_n(cJSON *object, const char *string,size_t n , cJSON *item)
54 : {
55 69 : if (!item)
56 : {
57 69 : return;
58 : }
59 :
60 : /* free old key and set new one */
61 66 : if (item->string)
62 : {
63 1 : free(item->string);
64 : }
65 66 : item->string = (char*)cJSON_strdup_n((const unsigned char*)string,n);
66 66 : cJSON_AddItemToArray(object,item);
67 : }
68 :
69 : // create a string object from a non null terminated string
70 59 : cJSON *cJSON_CreateString_n(const char *string, size_t n)
71 : {
72 59 : cJSON *item = cJSON_CreateObject();
73 59 : if(item)
74 : {
75 59 : item->type = cJSON_String;
76 59 : item->valuestring = (char*)cJSON_strdup_n((const unsigned char*)string, n);
77 59 : if(!item->valuestring)
78 : {
79 0 : cJSON_Delete(item);
80 0 : return NULL;
81 : }
82 : }
83 :
84 59 : return item;
85 : }
86 :
87 : /* insert item at the beginning of the array/object. */
88 7 : void cJSON_AddItemToBeginArray(cJSON *array, cJSON *item)
89 : {
90 7 : if (!array) return;
91 6 : cJSON *c = array->child;
92 6 : if (!item)
93 : {
94 : return;
95 : }
96 5 : if (!c)
97 : {
98 : /* list is empty, start new one */
99 4 : array->child = item;
100 : }
101 : else
102 : {
103 1 : array->child=item;
104 1 : item->next=c;
105 1 : c->prev=item;
106 : }
107 : }
108 :
109 : // create an JSON tree from **envp
110 : // but only for environment vars starting with : CI_, GITLAB_ or DEPLOY_
111 1 : cJSON * cJSON_Create_env_obj(char** envp)
112 : {
113 1 : cJSON *environment = cJSON_CreateObject();
114 : char** env;
115 6 : for (env = envp; *env != 0; env++)
116 : {
117 5 : char* thisEnv = *env;
118 : //printf("thisenv: %s\n", thisEnv);
119 :
120 5 : char * e=thisEnv;
121 5 : int len=(int)strlen(thisEnv);
122 5 : int pos = 0;
123 5 : while (*e++ != '=' && pos < len) pos++;
124 5 : if (pos != len && pos >4)
125 : {
126 5 : if (strncmp(thisEnv,"CI_",3)==0 || \
127 2 : ( pos >8 && strncmp(thisEnv,"DEPLOY_",7)==0 )|| \
128 1 : ( pos>7 && strncmp(thisEnv,"GITLAB",6)==0) ) \
129 : {
130 4 : cJSON_AddItemToObject_n(environment, thisEnv, pos, cJSON_CreateString(thisEnv+pos+1));
131 : }
132 : }
133 : }
134 1 : return environment;
135 : }
136 :
137 : // compaire a string value of a key, check if present and compaire
138 : // returns 0 if match
139 62 : int validate_key(cJSON * item, const char * key,const char * value )
140 : {
141 62 : if (!key || !item) return -2;
142 62 : if (item->type==cJSON_String && !value) return -1;
143 62 : cJSON * tmp_json=cJSON_GetObjectItem(item, key );
144 62 : if (tmp_json)
145 : {
146 51 : if (tmp_json->valuestring && value)
147 49 : return(strcmp(value,tmp_json->valuestring)); // return 0 on equal string
148 2 : else if (!value && !tmp_json->valuestring)
149 : return 0; // NULL==NULL
150 : else
151 2 : return -1;
152 : }
153 : else
154 : {
155 :
156 : return(-1);
157 : //else return 0; // no item == no value
158 : }
159 : }
160 :
161 : // get a key valuestring but check if exist
162 : // return NULL on non exist
163 4 : int get_key(cJSON * item, const char * key,char ** value )
164 : {
165 :
166 4 : if (!key) return -2;
167 3 : cJSON * tmp_json=cJSON_GetObjectItem(item, key );
168 3 : if (tmp_json)
169 : {
170 2 : if (value) *value=tmp_json->valuestring;
171 : return (0);
172 : }
173 : else
174 : {
175 : return(-1);
176 : }
177 : }
178 :
179 : // parse the JSON env-tree to an **envp
180 1 : int parse_env(cJSON * env_json, char *** newevpp)
181 : {
182 : int i;
183 : size_t len;
184 1 : int array_size = cJSON_GetArraySize(env_json);
185 1 : *newevpp=calloc(sizeof(char *), array_size+1);
186 1 : char**walk=*newevpp;
187 6 : for (i = 0; i < array_size; i++)
188 : {
189 5 : cJSON *subitem = cJSON_GetArrayItem(env_json, i);
190 5 : if (cJSON_IsString(subitem))
191 : {
192 5 : len=strlen(subitem->string)+1+strlen(subitem->valuestring) +1;
193 5 : *walk=calloc(1, len);
194 5 : sprintf(*walk, "%s=%s",subitem->string,subitem->valuestring);
195 : // printf("%s\n",*walk);
196 : }
197 5 : walk++;
198 : }
199 1 : return (0);
200 : }
201 :
202 : // cleanup of env created with : int parse_env(cJSON * env_json, char *** newevpp)
203 1 : void free_envp(char *** envp)
204 : {
205 1 : char ** walk = *envp;
206 7 : while (*walk)
207 : {
208 5 : if (*walk) free(*walk);
209 5 : *walk=NULL;
210 5 : walk ++;
211 : }
212 1 : free(*envp);
213 1 : *envp=NULL;
214 1 : }
215 :
216 :
217 : // check if item is present in json string array
218 5 : int in_string_array(cJSON * json_list, char * search)
219 : {
220 5 : if (!json_list || json_list->type==cJSON_NULL || json_list->type==cJSON_Invalid) return -3;
221 4 : if (!search) return 0;
222 :
223 3 : cJSON * pos=NULL;
224 3 : int found=0;
225 8 : cJSON_ArrayForEach(pos,json_list)
226 : {
227 7 : if (pos->valuestring && strcmp(search,pos->valuestring)==0)
228 : {
229 : found =1;
230 : break;
231 : }
232 : }
233 3 : return !found;
234 : }
235 :
236 : // check if list of keys is present in JSON structure
237 55 : int check_presence(cJSON * env_json, char ** list, struct trace_Struct *trace)
238 : {
239 55 : if (!env_json || !trace) return -1;
240 51 : if (!list) return 0;
241 : char** item;
242 : int result=0;
243 408 : for (item = list; *item != NULL; item++)
244 : {
245 408 : if(!cJSON_GetObjectItem(env_json, *item))
246 : {
247 4 : result++;
248 :
249 4 : Write_dyn_trace(trace, red,"\nERROR: Missing \"%s\"\n",*item);
250 :
251 : }
252 : }
253 : return result;
254 : }
255 :
256 : // get's the object->valuestring of key
257 : // return NULL on non exiting
258 : // return a null terminated string,
259 : // caller should not freeit, points to string in object
260 566 : char * cJSON_get_key(cJSON * item, const char * key)
261 : {
262 566 : if (!item || !key ) return NULL;
263 566 : char * result=NULL;
264 566 : cJSON * thisitem=cJSON_GetObjectItem(item, key);
265 566 : if (thisitem) result=thisitem->valuestring;
266 566 : return result;
267 : }
|