15 #include <emailformatter.h>
18 #include <libfossdb.h>
37 #define EMAIL_ERROR(...) { \
38 WARNING(__VA_ARGS__); \
42 #define EMAIL_BUILD_CMD "%s %s -s '%s' %s"
43 #define DEFAULT_HEADER "FOSSology scan complete\nmessage:\""
44 #define DEFAULT_FOOTER "\""
45 #define DEFAULT_SUBJECT "FOSSology scan complete\n"
46 #define DEFAULT_COMMAND "/usr/bin/mailx"
48 #define min(x, y) (x < y ? x : y)
87 gchar* m_str = g_match_info_fetch(
match, 1);
89 gchar* fossy_url = args->foss_url;
90 job_t* job = args->job;
91 GPtrArray* rows = NULL;
101 if(strcmp(m_str,
"UPLOADNAME") == 0)
106 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
108 g_string_append_printf(ret,
109 "[ERROR: unable to select upload file name for job %d]", job->
id);
111 else if(PQntuples(db_result) == 0)
114 g_string_append_printf(ret,
115 "[File has been deleted by job %d]", job->
id);
117 g_string_append_printf(ret,
118 "[ERROR: file has not been uploaded or unpacked yet for job %d]", job->
id);
122 g_string_append(ret, PQgetvalue(db_result, 0, 0));
134 else if(strcmp(m_str,
"BROWSELINK") == 0)
139 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
141 g_string_append_printf(ret,
142 "[ERROR: unable to select upload primary key for job %d]", job->
id);
144 else if(PQntuples(db_result) == 0)
147 g_string_append_printf(ret,
148 "[File has been deleted by job %d]", job->
id);
150 g_string_append_printf(ret,
151 "[ERROR: file has not been uploaded or unpacked yet for job %d]", job->
id);
155 g_string_append_printf(ret,
156 "http://%s?mod=browse&upload=%s&item=%s&show=detail",
157 fossy_url, PQgetvalue(db_result, 0, 0), PQgetvalue(db_result, 0, 1));
168 else if(strcmp(m_str,
"JOBQUEUELINK") == 0)
173 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
175 g_string_append_printf(ret,
176 "[ERROR: unable to select file name for upload %d]", job->
id);
180 g_string_append_printf(ret,
"http://%s?mod=showjobs&upload=%s",
181 fossy_url, PQgetvalue(db_result, 0, 0));
192 else if(strcmp(m_str,
"SCHEDULERLOG") == 0)
194 g_string_append_printf(ret,
"http://%s?mod=showjobs&job=%d",
202 else if(strcmp(m_str,
"UPLOADFOLDERNAME") == 0)
207 if(PQresultStatus(db_result) != PGRES_TUPLES_OK || PQntuples(db_result) == 0)
209 g_string_append_printf(ret,
210 "[NOTICE: unable to select folder name for upload %d]", job->
id);
214 rows = g_ptr_array_new();
215 GString *foldername = g_string_new(PQgetvalue(db_result, 0, 0));
216 guint folder_pk = atoi(PQget(db_result, 0,
"folder_pk"));
217 g_ptr_array_add(rows, foldername);
229 while(PQresultStatus(db_result) == PGRES_TUPLES_OK && PQntuples(db_result) == 1)
231 GString *foldername = g_string_new(PQgetvalue(db_result, 0, 0));
232 guint folder_pk = atoi(PQget(db_result, 0,
"folder_pk"));
233 g_ptr_array_add(rows, foldername);
244 for(i = rows->len - 1; i > 0; i--)
246 GString *folder = g_ptr_array_index(rows, i);
247 g_string_append(ret, folder->str);
248 g_string_append(ret,
" / ");
250 GString *folder = g_ptr_array_index(rows, 0);
251 g_string_append(ret, folder->str);
252 g_ptr_array_free(rows, TRUE);
263 else if(strcmp(m_str,
"JOBRESULT") == 0)
267 case JB_COMPLETE: g_string_append(ret,
"COMPLETE");
break;
268 case JB_FAILED: g_string_append(ret,
"FAILED");
break;
270 g_string_append_printf(ret,
"[ERROR: illegal job status \"%s\"]",
271 job_status_strings[job->
status]);
280 else if(strcmp(m_str,
"AGENTSTATUS") == 0)
284 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
286 g_string_append_printf(ret,
287 "[ERROR: unable to select agent info for job %d]", job->
id);
291 rows = g_ptr_array_sized_new(PQntuples(db_result));
296 for(i = 0; i < PQntuples(db_result) && ret; i++)
299 data->
id = atoi(PQget(db_result, i,
"jq_pk"));
300 data->
agent = g_string_new(PQget(db_result, i,
"jq_type"));
301 if(atoi(PQget(db_result, i,
"jq_end_bits")) == 1)
309 g_ptr_array_add(rows, data);
313 g_ptr_array_free(rows, TRUE);
323 else if(strcmp(m_str,
"DB") == 0)
325 g_string_append(ret,
"[DB. syntax is NOT IMPLEMENTED]");
374 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
376 PQ_ERROR(db_result,
"unable to check job status for jq_pk %d", job->
id);
383 if(PQntuples(db_result) != 0)
395 for(i = 0; i < PQntuples(db_result) && ret; i++)
397 id = atoi(PQget(db_result, i,
"jq_pk"));
398 if(
id != job->
id && g_tree_lookup(scheduler->
job_list, &
id) != NULL)
406 for(i = 0; i < PQntuples(db_result) && ret; i++)
408 if(atoi(PQget(db_result, i,
"jq_end_bits")) == (1 << 1))
437 char* final_cmd = NULL;
441 job_status curr_status = job->
status;
450 if(PQresultStatus(db_result) != PGRES_TUPLES_OK || PQntuples(db_result) == 0)
452 PQ_ERROR(db_result,
"unable to select the upload id for job %d", j_id);
456 upload_id = atoi(PQgetvalue(db_result, 0, 0));
461 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
463 PQ_ERROR(db_result,
"unable to check common uploads to job %d", j_id);
470 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
472 PQ_ERROR(db_result,
"unable to access email info for job %d", j_id);
479 if(PQntuples(db_result) == 0)
484 if(PQresultStatus(db_result) != PGRES_TUPLES_OK || PQntuples(db_result) == 0)
486 PQ_ERROR(db_result,
"unable to access email info for job %d", j_id);
491 if(PQget(db_result, 0,
"email_notify")[0] ==
'y')
496 email_txt = g_string_new(
"");
498 g_string_append(email_txt, job->
message == NULL ?
"" : job->
message);
504 args.foss_url = scheduler->
host_url;
506 args.scheduler = scheduler;
507 val = g_regex_replace_eval(scheduler->
parse_db_email, email_txt->str,
508 email_txt->len, 0, 0, (GRegexEvalCallback)
email_replace, &args, NULL);
512 val = email_txt->str;
516 if(final_cmd == NULL)
520 g_string_free(email_txt, TRUE);
523 if((mail_io = popen(final_cmd,
"w")) != NULL)
525 fprintf(mail_io,
"%s", val);
527 retcode = WEXITSTATUS(pclose(mail_io));
535 WARNING(
"Unable to spawn email notification process: '%s'.\n",
538 job->
status = curr_status;
542 g_string_free(email_txt, TRUE);
559 int email_notify, fd;
560 struct stat header_sb = {};
561 struct stat footer_sb = {};
563 GError* error = NULL;
573 fname = g_strdup_printf(
"%s/%s", scheduler->
sysconfigdir,
576 EMAIL_ERROR(
"email notification setting group \"[EMAILNOTIFY]\" missing. Using defaults");
578 EMAIL_ERROR(
"email notification setting key \"header\" missing. Using default header");
579 if(email_notify && (fd = open(fname, O_RDONLY)) == -1)
580 EMAIL_ERROR(
"unable to open file for email header: %s", fname);
581 if(email_notify && fstat(fd, &header_sb) == -1)
582 EMAIL_ERROR(
"unable to fstat email header: %s", fname);
583 if(email_notify && (scheduler->
email_header = mmap(NULL, header_sb.st_size, PROT_READ,
584 MAP_SHARED, fd, 0)) == MAP_FAILED)
585 EMAIL_ERROR(
"unable to mmap email header: %s", fname);
591 fname = g_strdup_printf(
"%s/%s", scheduler->
sysconfigdir,
596 EMAIL_ERROR(
"email notification setting key \"footer\" missing. Using default footer");
597 if(email_notify && (fd = open(fname, O_RDONLY)) == -1)
598 EMAIL_ERROR(
"unable to open file for email footer: %s", fname);
599 if(email_notify && fstat(fd, &footer_sb) == -1)
600 EMAIL_ERROR(
"unable to fstat email footer: %s", fname);
601 if(email_notify && (scheduler->
email_footer = mmap(NULL, footer_sb.st_size, PROT_READ,
602 MAP_SHARED, fd, 0)) == MAP_FAILED)
603 EMAIL_ERROR(
"unable to mmap email footer: %s", fname);
614 EMAIL_ERROR(
"email notification setting key \"subject\" missing. Using default subject");
625 EMAIL_ERROR(
"email notification setting key \"client\" missing. Using default client");
664 char sqltmp[1024] = {0};
674 "jq_args",
"jq_end_bits",
"jq_endtext",
"jq_endtime",
"jq_host",
675 "jq_itemsprocessed",
"jq_job_fk",
"jq_log",
"jq_pk",
"jq_runonpfile",
676 "jq_schedinfo",
"jq_starttime",
"jq_type" }},
677 {
"sysconfig", 2, {
"conf_value",
"variablename" }},
678 {
"job", 2, {
"job_pk",
"job_upload_fk" }},
679 {
"folder", 2, {
"folder_name",
"folder_pk" }},
680 {
"foldercontents", 3, {
"child_id",
"foldercontents_mode",
"parent_fk" }},
681 {
"upload", 2, {
"upload_filename",
"upload_pk" }},
682 {
"uploadtree", 3, {
"parent",
"upload_fk",
"uploadtree_pk" }},
683 {
"users", 4, {
"email_notify",
"user_email",
"user_name",
"user_pk" }},
689 for(curr = cols; curr->
table; curr++)
692 sql = g_string_new(sqltmp);
693 g_string_append_printf(sql,
"'%s' AND column_name IN (", curr->
table);
694 for(i = 0; i < curr->
ncols; i++)
696 g_string_append_printf(sql,
"'%s'", curr->
columns[i]);
697 if(i != curr->
ncols - 1)
698 g_string_append(sql,
", ");
700 g_string_append(sql,
") ORDER BY column_name");
704 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
707 PQ_ERROR(db_result,
"could not check database tables");
712 if(PQntuples(db_result) != curr->
ncols)
718 for(i = 0, curr_row = 0; i < curr->
ncols; i++)
720 if(curr_row>=PQntuples(db_result) || strcmp(PQgetvalue(db_result, curr_row, 0), curr->
columns[i]) != 0)
732 g_string_free(sql, TRUE);
737 log_printf(
"FATAL %s.%d: Scheduler did not pass database check\n", __FILE__, __LINE__);
738 log_printf(
"FATAL %s.%d: Running fo_postinstall should fix the database schema\n", __FILE__, __LINE__);
752 gchar* dbconf = NULL;
755 dbconf = g_strdup_printf(
"%s/Db.conf", configdir);
758 if(error || PQstatus(ret) != CONNECTION_OK)
759 FATAL(
"Unable to connect to the database: \"%s\"", error);
779 if(PQresultStatus(db_result) == PGRES_TUPLES_OK && PQntuples(db_result) != 0)
780 scheduler->
host_url = g_strdup(PQgetvalue(db_result, 0, 0));
805 PGresult* ret = NULL;
807 V_SPECIAL(
"DATABASE: exec \"%s\"\n", sql);
809 ret = PQexec(scheduler->
db_conn, sql);
810 if(ret == NULL || PQstatus(scheduler->
db_conn) != CONNECTION_OK)
815 ret = PQexec(scheduler->
db_conn, sql);
830 if(PQresultStatus(db_result) != PGRES_COMMAND_OK)
831 PQ_ERROR(db_result,
"failed to perform database exec: %s", sql);
845 PGresult* pri_result;
848 char* value, * type, * host, * pfile, * parent, *jq_cmd_args;
853 WARNING(
"scheduler is closing, will not check the job queue");
859 if(PQresultStatus(db_result) != PGRES_TUPLES_OK)
861 PQ_ERROR(db_result,
"database update failed on call to PQexec");
865 V_SPECIAL(
"DB: retrieved %d entries from the job queue\n",
866 PQntuples(db_result));
867 for(i = 0; i < PQntuples(db_result); i++)
870 j_id = atoi(PQget(db_result, i,
"jq_pk"));
871 if(g_tree_lookup(scheduler->
job_list, &j_id) != NULL)
875 parent = PQget(db_result, i,
"jq_job_fk");
876 host = PQget(db_result, i,
"jq_host");
877 type = PQget(db_result, i,
"jq_type");
878 pfile = PQget(db_result, i,
"jq_runonpfile");
879 value = PQget(db_result, i,
"jq_args");
880 jq_cmd_args =PQget(db_result, i,
"jq_cmd_args");
883 host = (strlen(host) == 0) ? NULL : host;
884 if(jq_cmd_args != NULL)
885 jq_cmd_args = (strlen(jq_cmd_args) == 0) ? NULL : jq_cmd_args;
887 V_DATABASE(
"DB: jq_pk[%d] added:\n jq_type = %s\n jq_host = %s\n "
888 "jq_runonpfile = %d\n jq_args = %s\n jq_cmd_args = %s\n",
889 j_id, type, host, (pfile != NULL && pfile[0] !=
'\0'), value, jq_cmd_args);
892 if(strcmp(type,
"command") == 0)
894 WARNING(
"DB: commands in the job queue not implemented,"
895 " using the interface api instead");
901 if(PQresultStatus(pri_result) != PGRES_TUPLES_OK)
903 PQ_ERROR(pri_result,
"database update failed on call to PQexec");
906 if(PQntuples(pri_result)==0)
908 WARNING(
"can not find the user information of job_pk %s\n", parent);
914 atoi(PQget(pri_result, 0,
"user_pk")),
915 atoi(PQget(pri_result, 0,
"group_pk")),
916 atoi(PQget(pri_result, 0,
"job_priority")), jq_cmd_args);
917 job_set_data(scheduler, job, value, (pfile && pfile[0] !=
'\0'));
934 if(PQresultStatus(db_result) != PGRES_COMMAND_OK)
935 PQ_ERROR(db_result,
"failed to reset job queue");
956 case JB_NOT_AVAILABLE:
case JB_CHECKEDOUT:
959 sql = g_strdup_printf(
jobsql_started,
"localhost", getpid(), j_id);
977 if(sql != NULL && PQresultStatus(db_result) != PGRES_COMMAND_OK)
978 PQ_ERROR(db_result,
"failed to update job status in job queue");
980 if(status == JB_COMPLETE || status == JB_FAILED)
1010 sql = g_strdup_printf(
jobsql_log, log_name, j_id);
1024 PGresult* db_result;
1028 if(sql != NULL && PQresultStatus(db_result) != PGRES_COMMAND_OK)
1029 PQ_ERROR(db_result,
"failed to change job queue entry priority");
1041 char cmd[] =
"dpkg -s s-nail | grep -i 'Version' | awk '{print$2}' | cut -c -4";
1042 char version_str[128];
1044 float version_float;
1047 fp = popen(cmd,
"r");
1050 WARNING(
"Unable to run the command '%s'.\n", cmd);
1053 while(fgets(buf,
sizeof(buf), fp) != NULL)
1055 strcpy(version_str,buf);
1058 sscanf(version_str,
"%f", &version_float);
1060 if(version_float - 14.8 > 0.0001)
1075 PGresult* db_result_smtp;
1077 GString* client_cmd;
1078 GHashTable* smtpvariables;
1079 char* temp_smtpvariable;
1080 char* final_command;
1083 if(PQresultStatus(db_result_smtp) != PGRES_TUPLES_OK || PQntuples(db_result_smtp) == 0)
1085 PQ_ERROR(db_result_smtp,
"unable to get conf variables for SMTP from sysconfig");
1088 client_cmd = g_string_new(
"");
1089 smtpvariables = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1090 for(i = 0; i < PQntuples(db_result_smtp); i++)
1092 if(PQget(db_result_smtp, i,
"conf_value")[0])
1094 g_hash_table_insert(smtpvariables, g_strdup(PQget(db_result_smtp, i,
"variablename")),
1095 g_strdup(PQget(db_result_smtp, i,
"conf_value")));
1099 if(g_hash_table_contains(smtpvariables,
"SMTPHostName") && g_hash_table_contains(smtpvariables,
"SMTPPort"))
1101 if(g_hash_table_contains(smtpvariables,
"SMTPStartTls"))
1103 temp_smtpvariable = (
char *)g_hash_table_lookup(smtpvariables,
"SMTPStartTls");
1104 if(g_strcmp0(temp_smtpvariable,
"1") == 0)
1106 g_string_append_printf(client_cmd,
" -S smtp-use-starttls");
1109 if(g_hash_table_contains(smtpvariables,
"SMTPAuth"))
1111 temp_smtpvariable = (
char *)g_hash_table_lookup(smtpvariables,
"SMTPAuth");
1112 if(g_strcmp0(temp_smtpvariable,
"L") == 0)
1114 g_string_append_printf(client_cmd,
" -S smtp-auth=login");
1116 else if(g_strcmp0(temp_smtpvariable,
"P") == 0)
1118 g_string_append_printf(client_cmd,
" -S smtp-auth=plain");
1120 else if(g_strcmp0(temp_smtpvariable,
"N") == 0)
1122 g_string_append_printf(client_cmd,
" -S smtp-auth=none");
1125 if(g_hash_table_contains(smtpvariables,
"SMTPFrom"))
1127 g_string_append_printf(client_cmd,
" -S from=\"%s\"",
1128 (
char *)g_hash_table_lookup(smtpvariables,
"SMTPFrom"));
1130 if(g_hash_table_contains(smtpvariables,
"SMTPSslVerify"))
1132 temp_smtpvariable = (
char *)g_hash_table_lookup(smtpvariables,
"SMTPSslVerify");
1133 g_string_append(client_cmd,
" -S ssl-verify=");
1134 if(g_strcmp0(temp_smtpvariable,
"I") == 0)
1136 g_string_append(client_cmd,
"ignore");
1138 else if(g_strcmp0(temp_smtpvariable,
"S") == 0)
1140 g_string_append(client_cmd,
"strict");
1142 else if(g_strcmp0(temp_smtpvariable,
"W") == 0)
1144 g_string_append(client_cmd,
"warn");
1147 g_string_append_printf(client_cmd,
" -S v15-compat");
1150 g_string_append_printf(client_cmd,
" -S smtp=\"");
1154 g_string_append_printf(client_cmd,
" -S mta=\"");
1157 if((g_strcmp0((
char *)g_hash_table_lookup(smtpvariables,
"SMTPPort"),
"25") != 0)
1158 || g_strcmp0((
char *)g_hash_table_lookup(smtpvariables,
"SMTPStartTls"),
"1") == 0)
1160 g_string_append_printf(client_cmd,
"smtps://");
1164 g_string_append_printf(client_cmd,
"smtp://");
1166 if(g_hash_table_contains(smtpvariables,
"SMTPAuthUser"))
1168 temp_smtpvariable = g_hash_table_lookup(smtpvariables,
"SMTPAuthUser");
1169 g_string_append_uri_escaped(client_cmd, temp_smtpvariable, NULL, TRUE);
1170 if(g_hash_table_lookup(smtpvariables,
"SMTPAuthPasswd"))
1172 g_string_append_printf(client_cmd,
":");
1173 temp_smtpvariable = g_hash_table_lookup(smtpvariables,
"SMTPAuthPasswd");
1174 g_string_append_uri_escaped(client_cmd, temp_smtpvariable, NULL, TRUE);
1176 g_string_append_printf(client_cmd,
"@");
1177 g_string_append_printf(client_cmd,
"%s:%s\"", (
char *)g_hash_table_lookup(smtpvariables,
"SMTPHostName"),
1178 (
char *)g_hash_table_lookup(smtpvariables,
"SMTPPort"));
1180 temp_smtpvariable = NULL;
1186 NOTIFY(
"Unable to send email. SMTP host or port not found in the configuration.\n"
1187 "Please check Configuration Variables.");
1188 final_command = NULL;
1190 g_hash_table_destroy(smtpvariables);
1191 g_string_free(client_cmd, TRUE);
1192 return final_command;
int is_meta_special(meta_agent_t *ma, int special_type)
tests if a particular meta agent has a specific special flag set
Header file with agent related operations.
#define SAG_NOEMAIL
This agent should not send notification emails.
char * fo_config_get(fo_conf *conf, const char *group, const char *key, GError **error)
Gets an element based on its group name and key name. If the group or key is not found,...
@ fo_missing_key
Required key is missing.
@ fo_missing_group
Required group is missing.
job_t * job_init(GTree *job_list, GSequence *job_queue, char *type, char *host, int id, int parent_id, int user_id, int group_id, int priority, char *jq_cmd_args)
Create a new job.
void job_set_data(scheduler_t *scheduler, job_t *job, char *data, int sql)
PGconn * fo_dbconnect(char *DBConfFile, char **ErrorBuf)
Connect to a database. The default is Db.conf.
#define PQ_ERROR(pg_r,...)
PGresult * database_exec(scheduler_t *scheduler, const char *sql)
Executes an sql statement for the scheduler.
#define DEFAULT_HEADER
Default email header.
void database_reset_queue(scheduler_t *scheduler)
Resets any jobs in the job queue that are not completed.
void database_init(scheduler_t *scheduler)
void database_job_priority(scheduler_t *scheduler, job_t *job, int priority)
Changes the priority of a job queue entry in the database.
#define DEFAULT_COMMAND
Default email command to use.
void database_update_job(scheduler_t *scheduler, job_t *job, job_status status)
Change the status of a job in the database.
void database_update_event(scheduler_t *scheduler, void *unused)
Checks the job queue for any new entries.
static void check_tables(scheduler_t *scheduler)
Checks that any part of the database used by the scheduler is correct.
static gboolean email_replace(const GMatchInfo *match, GString *ret, email_replace_args *args)
Replaces the variables that are in the header and footer files.
int check_mta_support()
Find s-nail version to check if mta is supported.
#define EMAIL_BUILD_CMD
Email command format.
void database_job_log(int j_id, char *log_name)
Enters the name of the log file for a job into the database.
void database_exec_event(scheduler_t *scheduler, char *sql)
static void email_notification(scheduler_t *scheduler, job_t *job)
void email_init(scheduler_t *scheduler)
Loads information about the email that will be sent for job notifications.
static gint email_checkjobstatus(scheduler_t *scheduler, job_t *job)
Checks the database for the status of the job.
void database_job_processed(int j_id, int num)
Updates the number of items that a job queue entry has processed.
#define DEFAULT_SUBJECT
Default email subject.
#define DEFAULT_FOOTER
Default email footer.
char * get_email_command(scheduler_t *scheduler, char *user_email)
Build command to run to send email.
static PGconn * database_connect(gchar *configdir)
Creates and performs error checking for a new database connection.
int closing
Set if scheduler is shutting down.
#define SafePQclear(pgres)
const char * jobsql_started
const char * check_scheduler_tables
const char * jobsql_paused
const char * jobsql_failed
const char * upload_common
const char * jobsql_information
const char * jobsql_jobinfo
const char * parent_folder_name
const char * jobsql_processed
const char * jobsql_resetqueue
const char * basic_checkout
const char * url_checkout
const char * jobsql_restart
const char * jobsql_anyrunnable
const char * jobsql_complete
const char * jobsql_priority
const char * jobsql_email
const char * jobsql_jobendbits
const char * jobsql_email_job
const char * select_upload_fk
gboolean status
Agent status (Pass => true, fail => false)
guint id
Job queue id for the agent.
GString * agent
Agent name.
scheduler_t * scheduler
Current scheduler reference.
job_t * job
Current job structure.
gchar * foss_url
Fossology URL string.
int32_t id
The identifier for this job.
job_status status
The current status for the job.
gchar * message
Message that will be sent with job notification email.
char * agent_type
The type of agent used to analyze the data.
Store the results of a regex match.
Data type used to check if the database is correct.
char * columns[13]
The columns that the scheduler uses for this table.
char * table
The name of the table to check columns in.
uint8_t ncols
The number of columns in the table that the scheduler uses.
GTree * job_list
List of jobs that have been created.
gchar * email_header
The beginning of the email message.
gchar * email_command
The command that will sends emails, usually mailx.
gchar * sysconfigdir
The system directory that contain fossology.conf.
PGconn * db_conn
The database connection.
GTree * meta_agents
List of all meta agents available to the scheduler.
gboolean default_footer
Is the footer the default footer.
gchar * email_subject
The subject to be used for emails.
GRegex * parse_db_email
Parses database email text.
gchar * email_footer
The end of the email message.
GSequence * job_queue
heap of jobs that still need to be started
gboolean default_header
Is the header the default header.
gchar * host_url
The url that is used to get to the FOSSology instance.
fo_conf * sysconfig
Configuration information loaded from the configuration file.