FOSSology  4.4.0
Open Source License Compliance by Open Source Software
json_writer.c
1 /*
2  SPDX-FileCopyrightText: © 2019 Siemens AG
3  Author: Gaurav Mishra <mishra.gaurav@siemens.com>
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 #include "json_writer.h"
9 #include "nomos.h"
10 #include "nomos_utils.h"
11 #include <json-c/json.h>
12 
13 static void writeHighlightInfoToJson(GArray* theMatches, json_object *resultsArray) {
14  int currentLicence;
15  for (currentLicence = 0; currentLicence < theMatches->len; ++currentLicence) {
16  LicenceAndMatchPositions* theLicence = getLicenceAndMatchPositions(theMatches, currentLicence);
17 
18  int highl;
19  for (highl = 0; highl < theLicence->matchPositions->len; ++highl) {
20  MatchPositionAndType* ourMatchv = getMatchfromHighlightInfo(theLicence->matchPositions, highl);
21  json_object *result = json_object_new_object();
22  json_object_object_add(result, "license", json_object_new_string(theLicence->licenceName));
23  json_object_object_add(result, "start", json_object_new_int(ourMatchv->start));
24  json_object_object_add(result, "end", json_object_new_int(ourMatchv->end));
25  json_object_object_add(result, "len", json_object_new_int(ourMatchv->end - ourMatchv->start));
26  json_object_array_add(resultsArray, result);
27  }
28  }
29 }
30 
31 void writeJson()
32 {
33  char realPathOfTarget[PATH_MAX];
34  json_object *result = json_object_new_object();
35  json_object *resultsArray = json_object_new_array();
36  json_object *licenses = json_object_new_array();
37  json_object *fileLocation = NULL;
38  json_object *aLicense = NULL;
39  size_t i = 0;
40 
41  if (optionIsSet(OPTS_HIGHLIGHT_STDOUT)) {
42  writeHighlightInfoToJson(cur.theMatches, resultsArray);
43  }
44  else{
46  while (cur.licenseList[i] != NULL)
47  {
48  aLicense = json_object_new_string(cur.licenseList[i]);
49  cur.licenseList[i] = NULL;
50  json_object_array_add(licenses, aLicense);
51  ++i;
52  }
53  }
54 
55  if (optionIsSet(OPTS_LONG_CMD_OUTPUT)
56  && realpath(cur.targetFile, realPathOfTarget))
57  {
58  fileLocation = json_object_new_string(realPathOfTarget);
59  }
60  else
61  {
62  fileLocation = json_object_new_string(basename(cur.targetFile));
63  }
64  json_object_object_add(result, "file", fileLocation);
65  if (optionIsSet(OPTS_HIGHLIGHT_STDOUT)){
66  json_object_object_add(result, "licenses", resultsArray);
67  }
68  else{
69  json_object_object_add(result, "licenses", licenses);
70  }
71 
72  char *prettyJson = unescapePathSeparator(
73  json_object_to_json_string_ext(result, JSON_C_TO_STRING_PRETTY));
74  sem_wait(mutexJson);
75  if (*printcomma)
76  {
77  printf(",%s\n", prettyJson);
78  }
79  else
80  {
81  *printcomma = true;
82  printf("%s\n", prettyJson);
83  }
84  fflush(stdout);
85  sem_post(mutexJson);
86  free(prettyJson);
87  json_object_put(result);
88 }
89 
90 char *unescapePathSeparator(const char* json)
91 {
92  const char *escapedSeparator = "\\/";
93  const char *pathSeparator = "/";
94  const int escPathLen = 2;
95  const int pathSepLen = 1;
96  size_t resultLength = 0;
97  size_t remainingLength = -1;
98  char *result;
99  char *tmp;
100  char *tempjson;
101  int count;
102  if (!json)
103  {
104  return NULL;
105  }
106  tempjson = strdup(json);
107 
108  tmp = tempjson;
109  for (count = 0; (tmp = strstr(tmp, escapedSeparator)); count++)
110  {
111  tmp += escPathLen;
112  }
113 
114  resultLength = strlen(tempjson) - ((escPathLen - pathSepLen) * count);
115 
116  result = (char*) calloc(resultLength + 1, sizeof(char));
117 
118  strncpy(result, strtok(tempjson, escapedSeparator), resultLength);
119  remainingLength = resultLength - strlen(result);
120 
121  while (count-- && remainingLength > 0)
122  {
123  strncat(result, pathSeparator, remainingLength);
124  strncat(result, strtok(NULL, escapedSeparator), remainingLength - 1);
125  remainingLength = resultLength - strlen(result);
126  }
127  free(tempjson);
128  return result;
129 }
130 
131 inline void initializeJson()
132 {
133  mutexJson = (sem_t *) mmap(NULL, sizeof(sem_t),
134  PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
135  printcomma = (gboolean *) mmap(NULL, sizeof(gboolean),
136  PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
137  sem_init(mutexJson, 2, SEM_DEFAULT_VALUE);
138 }
139 
140 inline void destroyJson()
141 {
142  sem_destroy(mutexJson);
143  munmap(printcomma, sizeof(gboolean));
144  munmap(mutexJson, sizeof(sem_t));
145 }
Handle JSON outputs.
void writeJson()
Write the scan output as a JSON.
Definition: json_writer.c:31
void initializeJson()
Definition: json_writer.c:131
char * unescapePathSeparator(const char *json)
Unescape the path separator from JSON.
Definition: json_writer.c:90
void destroyJson()
Definition: json_writer.c:140
Nomos header file.
int optionIsSet(int val)
Check if an CLI option is set.
Definition: nomos_utils.c:560
sem_t * mutexJson
Mutex to handle JSON writes.
Definition: nomos_utils.c:21
FUNCTION void parseLicenseList()
parse the comma separated list of license names found
Definition: nomos_utils.c:450
FUNCTION MatchPositionAndType * getMatchfromHighlightInfo(GArray *in, int index)
Get the MatchPositionAndType for a given index in highlight array.
Definition: nomos_utils.c:901
FUNCTION LicenceAndMatchPositions * getLicenceAndMatchPositions(GArray *in, int index)
Get the LicenceAndMatchPositions for a given index in match array.
Definition: nomos_utils.c:913
gboolean * printcomma
True to print comma while printing JSON object.
Definition: nomos_utils.c:22
GArray * matchPositions
Match positions.
Definition: nomos.h:379
char * licenceName
License names.
Definition: nomos.h:381
int start
Start position of match.
Definition: nomos.h:370
int end
End position of match.
Definition: nomos.h:371
GArray * theMatches
Definition: nomos.h:417
char targetFile[myBUFSIZ]
Definition: nomos.h:394
char * licenseList[512]
Definition: nomos.h:414