FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
mimetype.c
Go to the documentation of this file.
1 /***************************************************************
2  Copyright (C) 2007-2013 Hewlett-Packard Development Company, L.P.
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License along
14  with this program; if not, write to the Free Software Foundation, Inc.,
15  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  ***************************************************************/
64 #include "finder.h"
65 
66 #ifdef COMMIT_HASH_S
67 char BuildVersion[]="mimetype build version: " VERSION_S " r(" COMMIT_HASH_S ").\n";
68 #else
69 char BuildVersion[]="mimetype build version: NULL.\n";
70 #endif
71 
78 int main(int argc, char *argv[])
79 {
80  int arg;
81  char *Parm = NULL;
82  char *Path = NULL;
83  int c;
84  char *agent_desc = "Determines mimetype for each file";
85  int pfile_count = 0;
86  int Agent_pk;
87  int ars_pk = 0;
88 
89  int upload_pk = 0; // the upload primary key
90  int user_pk = 0;
91  char *AgentARSName = "mimetype_ars";
92  int rv;
93  PGresult *result;
94  char sqlbuf[1024];
95  int CmdlineFlag = 0;
96  char *COMMIT_HASH;
97  char *VERSION;
98  char agent_rev[MAXCMD];
99 
100  /* initialize the scheduler connection */
101  fo_scheduler_connect(&argc, argv, &pgConn);
102 
103  /* Process command-line */
104  while((c = getopt(argc,argv,"iCc:hvV")) != -1)
105  {
106  switch(c)
107  {
108  case 'i':
109  PQfinish(pgConn);
110  return(0);
111  case 'c':
112  /* do nothing with this option */
113  break;
114  case 'C':
115  CmdlineFlag = 1;
116  break;
117  case 'v':
118  agent_verbose++;
119  break;
120  case 'V':
121  printf("%s", BuildVersion);
122  PQfinish(pgConn);
123  return(0);
124  default:
125  Usage(argv[0]);
126  PQfinish(pgConn);
127  exit(-1);
128  }
129  }
130 
131  COMMIT_HASH = fo_sysconfig("mimetype", "COMMIT_HASH");
132  VERSION = fo_sysconfig("mimetype", "VERSION");
133  sprintf(agent_rev, "%s.%s", VERSION, COMMIT_HASH);
134  /* Get the Agent Key from the DB */
135  Agent_pk = fo_GetAgentKey(pgConn, basename(argv[0]), 0, agent_rev, agent_desc);
136 
137  FMimetype = fopen("/etc/mime.types","rb");
138  if (!FMimetype)
139  {
140  LOG_WARNING("Unable to open /etc/mime.types\n");
141  }
142 
143  MagicCookie = magic_open(MAGIC_PRESERVE_ATIME|MAGIC_MIME);
144  if (MagicCookie == NULL)
145  {
146  LOG_FATAL("Failed to initialize magic cookie\n");
147  PQfinish(pgConn);
148  exit(-1);
149  }
150  if (magic_load(MagicCookie,NULL) != 0)
151  {
152  LOG_FATAL("Failed to load magic file: UnMagic\n");
153  PQfinish(pgConn);
154  exit(-1);
155  }
156 
157  /* Run from the command-line (for testing) */
158  for(arg=optind; arg < argc; arg++)
159  {
160  Akey = -1;
161  strncpy(A,argv[arg],sizeof(A)-1);
162  A[sizeof(A)-1] = '\0';
163  DBCheckMime(A);
164  }
165 
166  /* Run from scheduler! */
167  if (0 == CmdlineFlag)
168  {
169  user_pk = fo_scheduler_userID(); /* get user_pk for user who queued the agent */
170 
171  while(fo_scheduler_next())
172  {
173  /* get piece of information, including upload_pk, others */
174  Parm = fo_scheduler_current();
175  if (Parm && Parm[0])
176  {
177  upload_pk = atoi(Parm);
178 
179  /* Check Permissions */
180  if (GetUploadPerm(pgConn, upload_pk, user_pk) < PERM_WRITE)
181  {
182  LOG_ERROR("You have no update permissions on upload %d", upload_pk);
183  continue;
184  }
185 
186  /* does ars table exist?
187  * If not, create it.
188  */
189  rv = fo_tableExists(pgConn, AgentARSName);
190  if (!rv)
191  {
192  rv = fo_CreateARSTable(pgConn, AgentARSName);
193  if (!rv) return(0);
194  }
195 
196  /* check ars table if this is duplicate request*/
197  memset(sqlbuf, 0, sizeof(sqlbuf));
198  snprintf(sqlbuf, sizeof(sqlbuf),
199  "select ars_pk from mimetype_ars,agent \
200  where agent_pk=agent_fk and ars_success=true \
201  and upload_fk='%d' and agent_fk='%d'",
202  upload_pk, Agent_pk);
203  result = PQexec(pgConn, sqlbuf);
204  if (fo_checkPQresult(pgConn, result, sqlbuf, __FILE__, __LINE__)) exit(-1);
205  if (PQntuples(result) > 0)
206  {
207  PQclear(result);
208  LOG_WARNING("Ignoring requested mimetype analysis of upload %d - Results are already in database.\n",upload_pk);
209  continue;
210  }
211  PQclear(result);
212 
213  /* Record analysis start in mimetype_ars, the mimetype audit trail. */
214  ars_pk = fo_WriteARS(pgConn, ars_pk, upload_pk, Agent_pk, AgentARSName, 0, 0);
215 
216  /* get all pfile ids on a upload record */
217  memset(sqlbuf, 0, sizeof(sqlbuf));
218  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT DISTINCT(pfile_pk) as Akey, pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size AS A FROM uploadtree, pfile WHERE uploadtree.pfile_fk = pfile.pfile_pk AND pfile_mimetypefk is NULL AND upload_fk = '%d';", upload_pk);
219  result = PQexec(pgConn, sqlbuf);
220  if (fo_checkPQresult(pgConn, result, sqlbuf, __FILE__, __LINE__)) exit(-1);
221  pfile_count = PQntuples(result);
222  int i;
223  for(i=0; i < pfile_count; i++)
224  {
225  Akey = atoi(PQgetvalue(result, i, 0));
226  strncpy(A, PQgetvalue(result, i, 1), sizeof(A)-1);
227  A[sizeof(A)-1] = '\0';
228  if (Akey <= 0 || A[0]=='\0')
229  {
230  printf("ERROR: Data is in an unknown format.\n");
231  PQfinish(pgConn);
232  exit(-1);
233  }
234 
235  /* Process the repository file */
236  /* Find the path */
237  Path = fo_RepMkPath("files",A);
238  if (Path && fo_RepExist("files",A))
239  {
240  /* Get the mimetype! */
241  DBCheckMime(Path);
242  }
243  else
244  {
245  printf("ERROR pfile %d Unable to process.\n",Akey);
246  printf("LOG pfile %d File '%s' not found.\n",Akey,A);
247  PQfinish(pgConn);
248  exit(-1);
249  }
250  /* Clean up Path memory */
251  if(Path)
252  {
253  free(Path);
254  Path = NULL;
255  }
257  }
258  PQclear(result);
259 
260  /* Record analysis success in mimetype_ars. */
261  if (ars_pk) fo_WriteARS(pgConn, ars_pk, upload_pk, Agent_pk, AgentARSName, 0, 1);
262  }
263  }
264  } /* if run from scheduler */
265 
266  /* Clean up */
267  if (FMimetype) fclose(FMimetype);
268  magic_close(MagicCookie);
269  if (DBMime) PQclear(DBMime);
270  if (pgConn) PQfinish(pgConn);
271  /* after cleaning up agent, disconnect from the scheduler, this doesn't return */
273  return(0);
274 } /* main() */
275 
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:181
PGresult * DBMime
contents of mimetype table
Definition: finder.c:27
char BuildVersion[]
Definition: buckets.c:79
PGconn * pgConn
Database connection.
Definition: adj2nest.c:98
char * fo_scheduler_current()
Get the last read string from the scheduler.
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
void fo_scheduler_connect(int *argc, char **argv, PGconn **db_conn)
Establish a connection between an agent and the scheduler.
char A[MAXCMD]
input for this system
Definition: finder.c:37
int agent_verbose
Common verbose flags for the agents, this is used so that the scheduler can change the verbose level ...
void DBCheckMime(char *Filename)
Given a file, check if it has a mime type in the DB.
Definition: finder.c:292
int fo_scheduler_userID()
Gets the id of the user that created the job that the agent is running.
Usage()
Print Usage statement.
Definition: fo_dbcheck.php:75
int Agent_pk
agent identifier
Definition: finder.c:30
char * fo_RepMkPath(const char *Type, char *Filename)
Given a filename, construct the full path to the file.
Definition: libfossrepo.c:364
FUNCTION int fo_CreateARSTable(PGconn *pgConn, const char *tableName)
Create ars table if it doesn&#39;t already exist.
Definition: libfossagent.c:284
int fo_tableExists(PGconn *pgConn, const char *tableName)
Check if table exists. Note, this assumes the database name is &#39;fossology&#39;.
Definition: libfossdb.c:243
FUNCTION int fo_GetAgentKey(PGconn *pgConn, const char *agent_name, long Upload_pk, const char *rev, const char *agent_desc)
Get the latest enabled agent key (agent_pk) from the database.
Definition: libfossagent.c:172
char * fo_scheduler_next()
Get the next data to process from the scheduler.
FUNCTION int fo_WriteARS(PGconn *pgConn, int ars_pk, int upload_pk, int agent_pk, const char *tableName, const char *ars_status, int ars_success)
Write ars record.
Definition: libfossagent.c:228
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
FUNCTION int GetUploadPerm(PGconn *pgConn, long UploadPk, int user_pk)
Get users permission to this upload.
Definition: libfossagent.c:385
FILE * FMimetype
for /etc/mime.types
Definition: finder.c:32
magic_t MagicCookie
for Magic
Definition: finder.c:34
int main(int argc, char *argv[])
Get the mimetype for a package.
Definition: mimetype.c:78
const char * upload_pk
Definition: sqlstatements.h:93
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.
#define PERM_WRITE
Read-Write permission.
Definition: libfossology.h:45
int fo_RepExist(char *Type, char *Filename)
Determine if a file exists.
Definition: libfossrepo.c:498