FOSSology  4.4.0
Open Source License Compliance by Open Source Software
monk.c
1 /*
2  Author: Daniele Fognini, Andreas Wuerl
3  SPDX-FileCopyrightText: © 2013-2015 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 #include "monk.h"
9 
10 #include "license.h"
11 #include "scheduler.h"
12 #include "cli.h"
13 #include "common.h"
14 #include "serialize.h"
15 #include <getopt.h>
16 
17 void parseArguments(MonkState* state, int argc, char** argv, int* fileOptInd) {
18  int c;
19  static struct option long_options[] = {{"config", required_argument, 0, 'c'},
20  {"userID", required_argument, 0, 'u'},
21  {"groupID", required_argument, 0, 'g'},
22  {"scheduler_start", no_argument, 0, 'S'},
23  {"jobId", required_argument, 0, 'j'},
24  {NULL, 0, NULL, 0}};
25  int option_index = 0;
26  while ((c = getopt_long(argc, argv, "VvJhIs:k:c:", long_options, &option_index)) != -1) {
27  switch (c) {
28  case 'c':
29  break;
30  case 'u':
31  case 'g':
32  case 'S':
33  case 'j':
34  /* these options are handled by the fo_scheduler_connect_dbMan call later in detail */
35  state->scanMode = MODE_SCHEDULER;
36  break;
37  case 'v':
38  state->verbosity++;
39  break;
40  case 'V':
41 #ifdef COMMIT_HASH_S
42  printf(AGENT_NAME " version " VERSION_S " r(" COMMIT_HASH_S ")\n");
43 #else
44  printf(AGENT_NAME " (no version available)\n");
45 #endif
46  state->scanMode = 0;
47  return;
48  case 'J':
49  state->json = 1;
50  break;
51  case 's':
52  state->scanMode = MODE_EXPORT_KOWLEDGEBASE;
53  state->knowledgebaseFile = optarg;
54  break;
55  case 'k':
56  state->scanMode = MODE_CLI_OFFLINE;
57  state->knowledgebaseFile = optarg;
58  break;
59  case 'I':
60  state->ignoreFilesWithMimeType = true;
61  break;
62  case 'h':
63  case '?':
64  default:
65  printf("Usage:\n"
66  "\nAs CLI tool using the licenses from the FOSSology database:\n");
67  printf(" %s [options] file [file [...]]\n", argv[0]);
68  printf(" options:\n"
69  " -h :: help (print this message), then exit.\n"
70  " -c config :: specify the directory for the system configuration.\n"
71  " -v :: verbose output.\n"
72  " -J :: JSON output.\n"
73  " file :: scan file and print licenses detected within it.\n"
74  " -V :: print the version info, then exit.\n"
75  "\nSave knowledgebase to knowledgebaseFile for offline usage without db:\n");
76  printf(" %s [options] -s knowledgebaseFile\n", argv[0]);
77  printf(" options:\n"
78  " -c config :: specify the directory for the system configuration.\n"
79  "\nUse previously saved knowledgebaseFile for offline usage without db.\n");
80  printf(" %s -k knowledgebaseFile [options] file [file [...]]\n", argv[0]);
81  printf(" options:\n"
82  " -J :: JSON output.\n"
83  " file :: scan file and print licenses detected within it.\n"
84  "\nThe following should only be called by the FOSSology scheduler:\n");
85  printf(" %s --scheduler_start [options]\n", argv[0]);
86  printf(" options:\n"
87  " -c config :: specify the directory for the system configuration.\n"
88  " --userID i :: the id of the user that created the job\n"
89  " --groupID i :: the id of the group of the user that created the job\n"
90  " --jobID i :: the id of the job\n");
91  state->scanMode = 0;
92  return;
93  }
94  }
95  *fileOptInd = optind;
96  if (optind < argc && state->scanMode != MODE_CLI_OFFLINE) {
97  state->scanMode = MODE_CLI;
98  }
99  if((state->scanMode == MODE_CLI_OFFLINE ||
100  state->scanMode == MODE_EXPORT_KOWLEDGEBASE) &&
101  state->knowledgebaseFile == NULL) {
102  fprintf( stderr, "necessary path to knowledgebase file not provided\n");
103  bail(state,4);
104  }
105 }
106 
107 int main(int argc, char** argv) {
108  int fileOptInd;
109 
110  MonkState stateStore = { .dbManager = NULL,
111  .agentId = 0,
112  .scanMode = 0,
113  .verbosity = 0,
114  .knowledgebaseFile = NULL,
115  .json = 0,
116  .ignoreFilesWithMimeType = false,
117  .ptr = NULL };
118  MonkState* state = &stateStore;
119  parseArguments(state, argc, argv, &fileOptInd);
120  int wasSuccessful = 1;
121 
122  if (state->scanMode == 0) {
123  return 0;
124  }
125 
126  Licenses* licenses;
127  if (state->scanMode != MODE_CLI_OFFLINE) {
128  int oldArgc = argc;
129  fo_scheduler_connect_dbMan(&argc, argv, &(state->dbManager));
130  fileOptInd = fileOptInd - oldArgc + argc;
131 
132  PGresult* licensesResult = queryAllLicenses(state->dbManager);
133  licenses = extractLicenses(state->dbManager, licensesResult, MIN_ADJACENT_MATCHES, MAX_LEADING_DIFF);
134  PQclear(licensesResult);
135  } else {
136  licenses = deserializeFromFile(state->knowledgebaseFile, MIN_ADJACENT_MATCHES, MAX_LEADING_DIFF);
137  }
138 
139  if (state->scanMode == MODE_SCHEDULER) {
140  wasSuccessful = handleSchedulerMode(state, licenses);
141  scheduler_disconnect(state, ! wasSuccessful);
142  } else if (state->scanMode == MODE_CLI ||
143  state->scanMode == MODE_CLI_OFFLINE) {
144  /* we no longer need a database connection */
145  if (state->dbManager != NULL) {
146  scheduler_disconnect(state, 0);
147  }
148  state->dbManager = NULL;
149 
150  wasSuccessful = handleCliMode(state, licenses, argc, argv, fileOptInd);
151  } else if (state->scanMode == MODE_EXPORT_KOWLEDGEBASE) {
152  printf("Write knowledgebase to %s\n", state->knowledgebaseFile);
153  wasSuccessful = serializeToFile(licenses, state->knowledgebaseFile);
154  }
155 
156  licenses_free(licenses);
157 
158  return ! wasSuccessful;
159 }
void bail(int exitval)
Disconnect with scheduler returning an error code and exit.
void fo_scheduler_connect_dbMan(int *argc, char **argv, fo_dbManager **dbManager)
Make a connection from an agent to the scheduler and create a DB manager as well.
Header file for the scheduler.
Definition: monk.h:67
Definition: monk.h:44