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