FOSSology  4.4.0
Open Source License Compliance by Open Source Software
libfossdb.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2011 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: LGPL-2.1-only
5 */
6 
12 #define ERRBUFSIZE 11264
13 
14 #include "libfossdb.h"
15 
16 #include <string.h>
17 
29 PGconn* fo_dbconnect(char* DBConfFile, char** ErrorBuf)
30 {
31  FILE* Fconf;
32  PGconn* pgConn;
33  char Line[1024];
34  char CMD[10240];
35  int i, CMDlen;
36  int C;
37  int PosEqual; /* index of "=" in Line */
38  int PosSemi; /* index of ";" in Line */
39  int BufLen;
40 
41  if (DBConfFile)
42  Fconf = fopen(DBConfFile, "r");
43  else
44  Fconf = fopen(FOSSDB_CONF, "r");
45  if (!Fconf)
46  {
47  *ErrorBuf = malloc(ERRBUFSIZE);
48  if (*ErrorBuf)
49  {
50  snprintf(*ErrorBuf, ERRBUFSIZE, "Database conf file: %s, ",
51  (DBConfFile ? DBConfFile : "FOSSDB_CONF"));
52  BufLen = strlen(*ErrorBuf);
53  strerror_r(errno, *ErrorBuf + BufLen, ERRBUFSIZE - BufLen);
54  }
55  return (NULL);
56  }
57 
58  /* read the configuration file */
59  memset(CMD, '\0', sizeof(CMD));
60  CMDlen = 0;
61  while (!feof(Fconf))
62  {
63  C = '@';
64  PosEqual = 0;
65  PosSemi = 0;
66  memset(Line, '\0', sizeof(Line));
67  /* read a line of data */
68  /* All lines are in the format: "field=value;" */
69  /* Lines beginning with "#" are ignored. */
70  for (i = 0; (i < sizeof(Line)) && (C != '\n') && (C > 0); i++)
71  {
72  C = fgetc(Fconf);
73  if ((C > 0) && (C != '\n')) Line[i] = C;
74  if ((C == '=') && !PosEqual) PosEqual = i;
75  else if ((C == ';') && !PosSemi) PosSemi = i;
76  }
77  /* check for a valid line */
78  if (PosSemi < PosEqual) PosEqual = 0;
79  if ((Line[0] != '#') && PosEqual && PosSemi)
80  {
81  /* looks good to me! */
82  if (CMD[0] != '\0')
83  {
84  CMD[CMDlen++] = ' ';
85  if (CMDlen >= sizeof(CMD))
86  {
87  fclose(Fconf);
88  goto BadConf;
89  }
90  }
91  Line[PosSemi] = '\0';
92  for (i = 0; i < PosEqual; i++)
93  {
94  if (!isspace(Line[i])) CMD[CMDlen++] = Line[i];
95  if (CMDlen >= sizeof(CMD))
96  {
97  fclose(Fconf);
98  goto BadConf;
99  }
100  }
101  CMD[CMDlen++] = '=';
102  if (CMDlen >= sizeof(CMD))
103  {
104  fclose(Fconf);
105  goto BadConf;
106  }
107  for (i = PosEqual + 1; Line[i] != '\0'; i++)
108  {
109  if (!isspace(Line[i])) CMD[CMDlen++] = Line[i];
110  if (CMDlen >= sizeof(CMD))
111  {
112  fclose(Fconf);
113  goto BadConf;
114  }
115  }
116  }
117  }
118 
119  /* done reading file */
120  fclose(Fconf);
121  if (CMD[0] == '\0') goto BadConf;
122 
123  /* Perform the connection */
124  pgConn = PQconnectdb(CMD);
125  if (PQstatus(pgConn) != CONNECTION_OK)
126  {
127  *ErrorBuf = malloc(ERRBUFSIZE);
128  if (*ErrorBuf)
129  {
130  int i = 0;
131  const char pass[10]= "password=";
132  for(i = strstr(CMD,pass) - CMD + strlen(pass); i < strlen(CMD); i++){
133  if(CMD[i] == ' '){
134  break;
135  }
136  CMD[i] ='*';
137  }
138  snprintf(*ErrorBuf, ERRBUFSIZE,
139  "ERROR: Unable to connect to the database\n Connection string: '%s'\n Connection status: '%d'\n Check: /usr/local/etc/fossology/Db.conf\n", CMD, PQstatus(pgConn));
140  }
141  return (NULL);
142  }
143 
144  return (pgConn);
145 
146  BadConf:
147  *ErrorBuf = malloc(ERRBUFSIZE);
148  snprintf(*ErrorBuf, ERRBUFSIZE, "Invalid Database conf file: %s, ",
149  (DBConfFile ? DBConfFile : "FOSSDB_CONF"));
150  return (NULL);
151 } /* fo_dbconnect() */
152 
153 
170 int fo_checkPQresult(PGconn* pgConn, PGresult* result, char* sql, char* FileID, int LineNumb)
171 {
172  if (!result)
173  {
174  printf("FATAL: %s:%d, %s\nOn: %s\n",
175  FileID, LineNumb, PQerrorMessage(pgConn), sql);
176  return -1;
177  }
178 
179  /* If no error, return */
180  if (PQresultStatus(result) == PGRES_TUPLES_OK) return 0;
181 
182  printf("ERROR: %s:%d, %s\nOn: %s\n",
183  FileID, LineNumb, PQresultErrorMessage(result), sql);
184  PQclear(result);
185  return (-1);
186 } /* fo_checkPQresult */
187 
188 
204 int fo_checkPQcommand(PGconn* pgConn, PGresult* result, char* sql, char* FileID, int LineNumb)
205 {
206  if (!result)
207  {
208  printf("FATAL: %s:%d, %sOn: %s\n",
209  FileID, LineNumb, PQerrorMessage(pgConn), sql);
210  return -1;
211  }
212 
213  /* If no error, return */
214  if (PQresultStatus(result) == PGRES_COMMAND_OK) return 0;
215 
216  printf("ERROR: %s:%d, %sOn: %s\n",
217  FileID, LineNumb, PQresultErrorMessage(result), sql);
218  PQclear(result);
219  return (-1);
220 } /* fo_checkPQcommand */
221 
222 
232 int fo_tableExists(PGconn* pgConn, const char* tableName)
233 {
234  char sql[256];
235  PGresult* result;
236  int TabCount;
237 
238  snprintf(sql, sizeof(sql),
239  "select count(*) from information_schema.tables where table_catalog='%s' and table_name='%s'",
240  PQdb(pgConn), tableName);
241  result = PQexec(pgConn, sql);
242  if (fo_checkPQresult(pgConn, result, sql, __FILE__, __LINE__)) return 0;
243 
244  TabCount = atol(PQgetvalue(result, 0, 0));
245 
246  PQclear(result);
247  return (TabCount);
248 } /* fo_tableExists() */
249 
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
cmdlist CMD[]
Global command table.
PGconn * fo_dbconnect(char *DBConfFile, char **ErrorBuf)
Connect to a database. The default is Db.conf.
Definition: libfossdb.c:29
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:170
int fo_tableExists(PGconn *pgConn, const char *tableName)
Check if table exists. Note, this assumes the database name is 'fossology'.
Definition: libfossdb.c:232
int fo_checkPQcommand(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres commands (not select) If an error occured, write the error to s...
Definition: libfossdb.c:204
char * DBConfFile
DB conf file location.
Definition: testRun.c:21