data.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. #ident "ldclt @(#)data.c 1.8 01/03/23"
  2. /** BEGIN COPYRIGHT BLOCK
  3. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  4. * Copyright (C) 2006 Red Hat, Inc.
  5. * All rights reserved.
  6. *
  7. * License: GPL (version 3 or any later version).
  8. * See LICENSE for details.
  9. * END COPYRIGHT BLOCK **/
  10. #ifdef HAVE_CONFIG_H
  11. # include <config.h>
  12. #endif
  13. /*
  14. FILE : data.c
  15. AUTHOR : Jean-Luc SCHWING
  16. VERSION : 1.0
  17. DATE : 11 January 1999
  18. DESCRIPTION :
  19. This file implements the management of the data that
  20. are manipulated by ldclt.
  21. It is targeted to contain all the functions needed for
  22. the images, etc...
  23. */
  24. #include <stdio.h> /* printf(), etc... */
  25. #include <stdlib.h> /* realloc(), etc... */
  26. #include <string.h> /* strlen(), etc... */
  27. #include <errno.h> /* errno, etc... */ /*JLS 06-03-00*/
  28. #include <sys/types.h> /* Misc types... */
  29. #include <sys/stat.h> /* stat(), etc... */
  30. #include <fcntl.h> /* open(), etc... */
  31. #include <lber.h> /* ldap C-API BER declarations */
  32. #include <ldap.h> /* ldap C-API declarations */
  33. #include <unistd.h> /* close(), etc... */
  34. #include <dirent.h> /* opendir(), etc... */
  35. #include <pthread.h> /* pthreads(), etc... */
  36. #include <sys/mman.h> /* mmap(), etc... */
  37. #include "port.h" /* Portability definitions */ /*JLS 28-11-00*/
  38. #include "ldclt.h" /* This tool's include file */
  39. /* ****************************************************************************
  40. FUNCTION : getExtend
  41. PURPOSE : Get the extension of the given string, i.e. the part
  42. that is after the last '.'
  43. INPUT : str = string to process
  44. OUTPUT : None.
  45. RETURN : The extension.
  46. DESCRIPTION :
  47. *****************************************************************************/
  48. char *getExtend (
  49. char *str)
  50. {
  51. int i;
  52. for (i=strlen(str)-1; (i>=0) && (str[i]!='.') ; i--);
  53. return (&(str[i+1]));
  54. }
  55. /* ****************************************************************************
  56. FUNCTION : loadImages
  57. PURPOSE : Load the images from the given directory.
  58. INPUT : dirpath = directory where the images are located.
  59. OUTPUT : None.
  60. RETURN : -1 if error, 0 else.
  61. DESCRIPTION :
  62. *****************************************************************************/
  63. int loadImages (
  64. char *dirpath)
  65. {
  66. DIR *dirp = NULL; /* Directory data */
  67. struct dirent *direntp; /* Directory entry */
  68. char *fileName; /* As read from the system */
  69. char name [1024]; /* To build the full path */
  70. struct stat stat_buf; /* To read the image size */
  71. int fd = -1; /* To open the image */
  72. int ret; /* Return value */
  73. int rc = 0;
  74. /*
  75. * Initialization
  76. */
  77. mctx.images = NULL;
  78. mctx.imagesNb = 0;
  79. mctx.imagesLast = -1;
  80. if ((ret = ldclt_mutex_init(&(mctx.imagesLast_mutex))) != 0)
  81. {
  82. fprintf (stderr, "ldclt: %s\n", strerror (ret));
  83. fprintf (stderr, "Error: cannot initiate imagesLast_mutex\n");
  84. fflush (stderr);
  85. rc = -1;
  86. goto exit;
  87. }
  88. /*
  89. * Open the directory
  90. */
  91. dirp = opendir (dirpath);
  92. if (dirp == NULL)
  93. {
  94. perror (dirpath);
  95. fprintf (stderr, "ldlct: cannot load images from %s\n", dirpath);
  96. fprintf (stderr, "ldclt: try using -e imagesdir=path\n"); /*JLS 06-03-01*/
  97. fflush (stderr);
  98. rc = -1;
  99. goto exit;
  100. }
  101. /*
  102. * Process the directory.
  103. * We will only accept the .jpg files, as stated by the RFC.
  104. */
  105. while ((direntp = readdir (dirp)) != NULL)
  106. {
  107. fileName = direntp->d_name;
  108. if (!strcmp (getExtend (fileName), "jpg"))
  109. {
  110. /*
  111. * Allocate a new image, and initiates with its name.
  112. */
  113. mctx.imagesNb++;
  114. mctx.images =
  115. (image *) realloc (mctx.images, mctx.imagesNb * sizeof (image));
  116. if (mctx.images == NULL) /*JLS 06-03-00*/
  117. { /*JLS 06-03-00*/
  118. printf ("Error: cannot realloc(mctx.images), error=%d (%s)\n",
  119. errno, strerror (errno)); /*JLS 06-03-00*/
  120. rc = -1;
  121. goto exit;
  122. } /*JLS 06-03-00*/
  123. mctx.images[mctx.imagesNb-1].name =
  124. (char *) malloc (strlen(fileName) + 1);
  125. if (mctx.images[mctx.imagesNb-1].name == NULL) /*JLS 06-03-00*/
  126. { /*JLS 06-03-00*/
  127. printf ("Error: cannot malloc(mctx.images[%d]).name, error=%d (%s)\n",
  128. mctx.imagesNb-1, errno, strerror (errno)); /*JLS 06-03-00*/
  129. rc = -1;
  130. goto exit;
  131. } /*JLS 06-03-00*/
  132. strcpy (mctx.images[mctx.imagesNb-1].name, fileName);
  133. /*
  134. * Read the image size
  135. */
  136. snprintf (name, sizeof(name), "%s/%s", dirpath, fileName);
  137. name[sizeof(name)-1] = '\0';
  138. /*
  139. * Open the image
  140. */
  141. fd = open (name, O_RDONLY);
  142. if (fd < 0)
  143. {
  144. perror (name);
  145. fprintf (stderr, "Cannot open(%s)\n", name);
  146. fflush (stderr);
  147. rc = -1;
  148. goto exit;
  149. }
  150. if (fstat (fd, &stat_buf) < 0)
  151. {
  152. perror (name);
  153. fprintf (stderr, "Cannot stat(%s)\n", name);
  154. fflush (stderr);
  155. rc = -1;
  156. goto exit;
  157. }
  158. mctx.images[mctx.imagesNb-1].length = stat_buf.st_size;
  159. /*
  160. * mmap() the image
  161. */
  162. mctx.images[mctx.imagesNb-1].data = mmap (0, stat_buf.st_size,
  163. PROT_READ, MAP_SHARED, fd, 0);
  164. if (mctx.images[mctx.imagesNb-1].data == (char *)MAP_FAILED)
  165. {
  166. perror (name);
  167. fprintf (stderr, "Cannot mmap(%s)\n", name);
  168. fflush (stderr);
  169. rc = -1;
  170. goto exit;
  171. }
  172. /*
  173. * Close the image. The mmap() will remain available, and this
  174. * close() will save file descriptors.
  175. */
  176. if (close (fd) < 0)
  177. {
  178. perror (name);
  179. fprintf (stderr, "Cannot close(%s)\n", name);
  180. fflush (stderr);
  181. rc = -1;
  182. goto exit;
  183. } else {
  184. fd = -1;
  185. }
  186. }
  187. } /* while ((direntp = readdir (dirp)) != NULL) */
  188. exit:
  189. /*
  190. * Close the directory
  191. */
  192. if (dirp && closedir (dirp) < 0)
  193. {
  194. perror (dirpath);
  195. fprintf (stderr, "Cannot closedir(%s)\n", dirpath);
  196. fflush (stderr);
  197. rc = -1;
  198. }
  199. /*
  200. * Normal end
  201. */
  202. if(fd != -1)
  203. close(fd);
  204. return rc;
  205. }
  206. /* ****************************************************************************
  207. FUNCTION : getImage
  208. PURPOSE : Add a random image to the given attribute.
  209. INPUT : None.
  210. OUTPUT : attribute = the attribute where the image should
  211. be added.
  212. RETURN : -1 if error, 0 else.
  213. DESCRIPTION :
  214. *****************************************************************************/
  215. int getImage (
  216. LDAPMod *attribute)
  217. {
  218. int imageNumber; /* The image we will select */
  219. int ret; /* Return value */
  220. /*
  221. * Select the next image
  222. */
  223. if ((ret = ldclt_mutex_lock (&(mctx.imagesLast_mutex))) != 0) /*JLS 29-11-00*/
  224. {
  225. fprintf (stderr,
  226. "Cannot mutex_lock(imagesLast_mutex), error=%d (%s)\n",
  227. ret, strerror (ret));
  228. fflush (stderr);
  229. return (-1);
  230. }
  231. mctx.imagesLast++;
  232. if (mctx.imagesLast == mctx.imagesNb)
  233. mctx.imagesLast = 0;
  234. imageNumber = mctx.imagesLast;
  235. if ((ret = ldclt_mutex_unlock (&(mctx.imagesLast_mutex))) != 0)
  236. {
  237. fprintf (stderr,
  238. "Cannot mutex_unlock(imagesLast_mutex), error=%d (%s)\n",
  239. ret, strerror (ret));
  240. fflush (stderr);
  241. return (-1);
  242. }
  243. /*
  244. * Create the data structure required
  245. */
  246. attribute->mod_bvalues = (struct berval **)
  247. malloc (2 * sizeof (struct berval *));
  248. if (attribute->mod_bvalues == NULL) /*JLS 06-03-00*/
  249. { /*JLS 06-03-00*/
  250. printf ("Error: cannot malloc(attribute->mod_bvalues), error=%d (%s)\n",
  251. errno, strerror (errno)); /*JLS 06-03-00*/
  252. return (-1); /*JLS 06-03-00*/
  253. } /*JLS 06-03-00*/
  254. attribute->mod_bvalues[0] = (struct berval *) malloc (sizeof (struct berval));
  255. if (attribute->mod_bvalues[0] == NULL) /*JLS 06-03-00*/
  256. { /*JLS 06-03-00*/
  257. printf ("Error: cannot malloc(attribute->mod_bvalues[0]), error=%d (%s)\n",
  258. errno, strerror (errno)); /*JLS 06-03-00*/
  259. return (-1); /*JLS 06-03-00*/
  260. } /*JLS 06-03-00*/
  261. attribute->mod_bvalues[1] = NULL;
  262. /*
  263. * Fill the bvalue with the image data
  264. */
  265. attribute->mod_bvalues[0]->bv_len = mctx.images[imageNumber].length;
  266. attribute->mod_bvalues[0]->bv_val = mctx.images[imageNumber].data;
  267. /*
  268. * Normal end
  269. */
  270. return (0);
  271. }
  272. /* ****************************************************************************
  273. FUNCTION : loadDataListFile
  274. PURPOSE : Load the data list file given in argument.
  275. INPUT : dlf->fname = file to process
  276. OUTPUT : dlf = file read
  277. RETURN : -1 if error, 0 else.
  278. DESCRIPTION :
  279. *****************************************************************************/
  280. int
  281. loadDataListFile (
  282. data_list_file *dlf)
  283. {
  284. FILE *ifile; /* Input file */
  285. char line[MAX_FILTER]; /* To read ifile */
  286. /*
  287. * Open the file
  288. */
  289. ifile = fopen (dlf->fname, "r");
  290. if (ifile == NULL)
  291. {
  292. perror (dlf->fname);
  293. fprintf (stderr, "Error: cannot open file \"%s\"\n", dlf->fname);
  294. return (-1);
  295. }
  296. /*
  297. * Count the entries.
  298. * Allocate the array.
  299. * Rewind the file.
  300. */
  301. for (dlf->strNb=0 ; fgets(line, MAX_FILTER, ifile) != NULL ; dlf->strNb++);
  302. dlf->str = (char **) malloc (dlf->strNb * sizeof (char *));
  303. if (fseek (ifile, 0, SEEK_SET) != 0)
  304. {
  305. perror (dlf->fname);
  306. fprintf (stderr, "Error: cannot rewind file \"%s\"\n", dlf->fname);
  307. fclose(ifile);
  308. return (-1);
  309. }
  310. /*
  311. * Read all the entries from this file
  312. */
  313. dlf->strNb=0;
  314. while (fgets(line, MAX_FILTER, ifile) != NULL)
  315. {
  316. if ((strlen (line) > 0) && (line[strlen(line)-1]=='\n'))
  317. line[strlen(line)-1] = '\0';
  318. dlf->str[dlf->strNb] = strdup (line);
  319. dlf->strNb++;
  320. }
  321. /*
  322. * Close the file
  323. */
  324. if (fclose (ifile) != 0)
  325. {
  326. perror (dlf->fname);
  327. fprintf (stderr, "Error: cannot fclose file \"%s\"\n", dlf->fname);
  328. return (-1);
  329. }
  330. return (0);
  331. }
  332. /* ****************************************************************************
  333. FUNCTION : dataListFile
  334. PURPOSE : Find the given data_list_file either in the list of
  335. files already loaded, either load it.
  336. INPUT : fname = file name.
  337. OUTPUT : None.
  338. RETURN : NULL if error, else the requested file.
  339. DESCRIPTION :
  340. *****************************************************************************/
  341. data_list_file *
  342. dataListFile (
  343. char *fname)
  344. {
  345. data_list_file *dlf; /* To process the request */
  346. /*
  347. * Maybe we already have loaded this file ?
  348. */
  349. for (dlf=mctx.dlf ; dlf != NULL ; dlf=dlf->next)
  350. if (!strcmp (fname, dlf->fname))
  351. return (dlf);
  352. /*
  353. * Well, it looks like we should load a new file ;-)
  354. * Allocate a new data structure, chain it in mctx and load the file.
  355. */
  356. dlf = (data_list_file *) malloc (sizeof (data_list_file));
  357. dlf->next = mctx.dlf;
  358. mctx.dlf = dlf;
  359. dlf->fname = strdup (fname);
  360. if (loadDataListFile (dlf) < 0)
  361. return (NULL);
  362. /*
  363. * Loaded...
  364. */
  365. return (dlf);
  366. }