PageRenderTime 67ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/main.c

https://bitbucket.org/jhg/sav-pfsense
C | 692 lines | 448 code | 34 blank | 210 comment | 65 complexity | c9d5371179bda2bad0f924c819917823 MD5 | raw file
  1. /*
  2. Sav-pfsense (C) 2011 Jesús Hernández Gormaz
  3. This program is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free Software
  5. Foundation; either version 3, or (at your option) any later version.
  6. This program is distributed in the hope that it will be useful, but WITHOUT ANY
  7. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  8. PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along with
  10. this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  11. Cambridge, MA 02139, USA.
  12. Este programa es software libre. Puede redistribuirlo y/o modificarlo bajo los
  13. términos de la Licencia Pública General de GNU según es publicada por la Free
  14. Software Foundation, bien de la versión 3 de dicha Licencia o bien (según su
  15. elección) de cualquier versión posterior.
  16. Este programa se distribuye con la esperanza de que sea útil, pero SIN NINGUNA
  17. GARANTÍA, incluso sin la garantía MERCANTIL implícita o sin garantizar la
  18. CONVENIENCIA PARA UN PROPÓSITO PARTICULAR. Para más detalles, véase la Licencia
  19. Pública General de GNU.
  20. Debería haber recibido una copia de la Licencia Pública General junto con este
  21. programa. En caso contrario, escriba a la Free Software Foundation, Inc., en 675
  22. Mass Ave, Cambridge, MA 02139, EEUU.
  23. */
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include "main.h"
  28. /*Entrar al portal de configuración de Pfsense y obtener una cookie de sesion,
  29. devuelve 0 si todo fue bien, usa wget*/
  30. int obtener_sesion_wget (char *ip);
  31. /*Validarse con un usuario y clave*/
  32. int validar_usuario_wget (char *ip, char *usuario, char *clave);
  33. /*Descarga el rollo de vouchers indicado*/
  34. int descargar_vouchers_wget (char *ip, unsigned int id, char *usuario, char *clave);
  35. /*Formatear vouchers descargados*/
  36. int formatear_vouchers (int id);
  37. /*Muestra un voucher y lo marca como usado, devuelve -1 en caso de que no queden
  38. vouchers*/
  39. int obtener_voucher (int rollo, char *voucher);
  40. /*Elimina un rollo de vouchers*/
  41. int eliminar_vouchers_wget (char *ip, unsigned int rollo, char *usuario, char *clave);
  42. /*Obtiene un campo oculto del formulario para crear vouchers*/
  43. int obtener_sid_wget (char *ip, char *sid);
  44. /*Crea el numero de rollo de vouchers indicado, indicando los minutos de
  45. duración, el numero de vouchers y un comentario*/
  46. int crear_vouchers_wget (char *ip, unsigned int rollo, unsigned int minutos,
  47. unsigned int numerovouchers, char *comentario,
  48. char *usuario, char *clave);
  49. /*Codifica la cadena segun la codificación URL*/
  50. int codificacion_url (char *cadena);
  51. /*Carga la lista local de rollos disponibles y devuelve el puntero al primer
  52. elemento o NULL si la lista esta vacia*/
  53. listarollos *cargar_lista_local_rollos ();
  54. /*Guarda la lista local de rollos*/
  55. int guardar_lista_local_rollos (listarollos *primero);
  56. /*Agregar un rollo a la lista de rollos, colocandolo en ultimo lugar*/
  57. int agregar_rollo_lista (listarollos **lista, unsigned int rollo, unsigned int minutos, unsigned int numerovouchers, char *comentario);
  58. /*Libera la memoria de la lista de rollos*/
  59. int liberar_lista_rollos (listarollos *primero);
  60. /*Asigna a id la posición en lista del rollo indicado, devuelve -1 si no existe*/
  61. int buscar_id_rollo (listarollos *primero, unsigned int rollo, unsigned int *id);
  62. /*Eliminar un rollo de la lista de rollos*/
  63. int eliminar_rollo_lista (listarollos **lista, unsigned int rollo);
  64. int main (int argc, char *argv[])
  65. {
  66. char voucher[512];
  67. /*descargar_vouchers_wget ("192.168.0.2", 0, "admin", "pfsense");
  68. obtener_voucher (0, &voucher[0]);
  69. printf ("voucher: %s\n", &voucher[0]);*/
  70. crear_vouchers_wget ("192.168.0.2", 1, 5, 90, "Prueba", "admin", "pfsense");
  71. crear_vouchers_wget ("192.168.0.2", 2, 5, 90, "Prueba", "admin", "pfsense");
  72. eliminar_vouchers_wget ("192.168.0.2", 1, "admin", "pfsense");
  73. return 0;
  74. }
  75. int obtener_sesion_wget (char *ip)
  76. {
  77. char comando[512];
  78. /*Formamos el comando*/
  79. sprintf (&comando[0],
  80. "wget -q -O %s --user-agent %s %s %s http://%s/index.php\0",
  81. ARCHIVO_PAGINA, NAVEGADOR, OPCIONES_WGET_COOKIES, ARCHIVO_COOKIE,
  82. ip);
  83. /*Ejecutamos el comando en el sistema*/
  84. system (&comando[0]);
  85. /*Eliminamos el archivo de la pagina ya que no la necesitamos*/
  86. remove (ARCHIVO_PAGINA);
  87. return 0;
  88. }
  89. int validar_usuario_wget (char *ip, char *usuario, char *clave)
  90. {
  91. char comando[512];
  92. /*Obtenemos una cookie de sesion*/
  93. obtener_sesion_wget (ip);
  94. /*Formamos el comando*/
  95. sprintf (&comando[0],
  96. "wget -q -O %s --user-agent %s --load-cookies %s %s %s --post-data usernamefld=%s\\&passwordfld=%s\\&login=Login --referer http://%s/index.php http://%s/index.php",
  97. ARCHIVO_PAGINA, NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES,
  98. ARCHIVO_COOKIE, usuario, clave, ip, ip);
  99. /*Ejecutamos el comando en el sistema*/
  100. system (&comando[0]);
  101. sprintf (&comando[0],
  102. "wget -q -O %s --user-agent %s --load-cookies %s %s %s --referer http://%s/index.php http://%s/",
  103. ARCHIVO_PAGINA, NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES,
  104. ARCHIVO_COOKIE, ip, ip);
  105. /*Ejecutamos el comando en el sistema*/
  106. system (&comando[0]);
  107. /*Eliminamos el archivo de la pagina ya que no la necesitamos*/
  108. remove (ARCHIVO_PAGINA);
  109. return 0;
  110. }
  111. int descargar_vouchers_wget (char *ip, unsigned int id, char *usuario, char *clave)
  112. {
  113. char comando[512];
  114. /*Nos validamos en el portal de administración de Pfsense*/
  115. validar_usuario_wget (ip, usuario, clave);
  116. /*Formamos el comando*/
  117. sprintf (&comando[0],
  118. "wget -q -O %s%u%s --user-agent %s --load-cookies %s %s %s --referer http://%s/ http://%s/services_captiveportal_vouchers.php?act=csv\\&id=%u",
  119. PREFIJO_ARCHIVO_VOUCHERS, id, EXTENSION_ARCHIVO_VOUCHERS,
  120. NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES, ARCHIVO_COOKIE,
  121. ip, ip, id);
  122. /*Ejecutamos el comando en el sistema*/
  123. system (&comando[0]);
  124. /*Formateamos los vouchers para simplificar su posterior lectura*/
  125. formatear_vouchers (id);
  126. /*Eliminamos la cookie para finalizar la sesion*/
  127. remove (ARCHIVO_COOKIE);
  128. return 0;
  129. }
  130. int formatear_vouchers (int id)
  131. {
  132. FILE *vouchers=NULL;
  133. FILE *formateados=NULL;
  134. char archivo[512];
  135. char linea[32];
  136. char *lineaformateada;
  137. unsigned int longitud;
  138. registrovoucher registro;
  139. /*Formamos la ruta al archivo de los vouchers descargados*/
  140. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, id,
  141. EXTENSION_ARCHIVO_VOUCHERS);
  142. /*Abrimos el archivo*/
  143. vouchers = fopen (&archivo[0], "r");
  144. /*Formamos la ruta al archivo de los vouchers formateados*/
  145. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, id, ".dat");
  146. /*Abrimos el archivo*/
  147. formateados = fopen (&archivo[0], "wb");
  148. /*Preparamos el registro como no usado*/
  149. registro.usado = 0;
  150. /*Leemos el resto del archivo completo linea a linea*/
  151. while (fgets (&linea[0], 32, vouchers) != NULL)
  152. {
  153. /*Comprobamos si debemos ignorar la linea por estar comentada*/
  154. if (linea[0] == '#') continue;
  155. /*Quitamos los dos primeros caracteres, una comilla y un espacio*/
  156. lineaformateada = &linea[2];
  157. /*Quitamos la comilla final*/
  158. longitud = strlen (&linea[0]);
  159. linea[longitud - 2] = '\0';
  160. /*Copiamos la cadena fomateada al registro*/
  161. strcpy (&registro.voucher[0], lineaformateada);
  162. /*Escribimos el registro*/
  163. fwrite (&registro, sizeof (registrovoucher), 1, formateados);
  164. }
  165. /*Cerramos los archivos*/
  166. fclose (vouchers);
  167. fclose (formateados);
  168. /*Formamos la ruta al archivo de los vouchers descargados*/
  169. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, id,
  170. EXTENSION_ARCHIVO_VOUCHERS);
  171. /*Eliminamos el archivo descargado*/
  172. remove (&archivo[0]);
  173. return 0;
  174. }
  175. int obtener_voucher (int rollo, char *voucher)
  176. {
  177. FILE *vouchers=NULL;
  178. char archivo[512];
  179. registrovoucher registro;
  180. unsigned int id=0;
  181. listarollos *rollos=NULL;
  182. /*Cargamos la lista de rollos*/
  183. rollos = cargar_lista_local_rollos ();
  184. /*Comprobamos que exista el rollo*/
  185. if (buscar_id_rollo (rollos, rollo, &id) != 0)
  186. {
  187. /*Liberamos la lista de rollos*/
  188. liberar_lista_rollos (rollos);
  189. return -1;
  190. }
  191. /*Liberamos la lista de rollos*/
  192. liberar_lista_rollos (rollos);
  193. rollos = NULL;
  194. /*Indicamos el valor por defecto, no usado*/
  195. registro.usado = 0;
  196. /*Indicamos que no se ha obtenido ningun voucher aun*/
  197. int obtenido=0;
  198. /*Formamos la ruta al archivo de los vouchers*/
  199. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, id, ".dat");
  200. /*Abrimos el archivo*/
  201. vouchers = fopen (&archivo[0], "r+b");
  202. while (!feof (vouchers) )
  203. {
  204. /*Cargamos un voucher*/
  205. fread (&registro, sizeof (registrovoucher), 1, vouchers );
  206. /*Comprobamos si ha sido usado*/
  207. if (registro.usado == 0)
  208. {
  209. /*Indicamos que esta usado*/
  210. registro.usado = 0xff;
  211. /*Lo guardamos en el archivo*/
  212. fseek (vouchers, - sizeof (registrovoucher), SEEK_CUR);
  213. fwrite (&registro, sizeof (registrovoucher), 1, vouchers);
  214. /*Indicamos que se ha encontrado un voucher*/
  215. obtenido = 1;
  216. /*Salimos del bucle*/
  217. break;
  218. }
  219. }
  220. /*Cerramos el archivo*/
  221. fclose (vouchers);
  222. /*comprobamos si se obtuvo un voucher*/
  223. if (obtenido == 0)
  224. {
  225. /*Cargamos la lista de rollos*/
  226. rollos = cargar_lista_local_rollos ();
  227. /*Eliminamos el rollo de vouchers por haber gastado ya todos*/
  228. eliminar_rollo_lista (&rollos, rollo);
  229. /*Liberamos la lista de rollos*/
  230. liberar_lista_rollos (rollos);
  231. rollos = NULL;
  232. return -1;
  233. }
  234. else
  235. {
  236. /*copiamos el voucher a la cadena indicada al llamar a la función*/
  237. strcpy (voucher, &registro.voucher[0]);
  238. }
  239. return 0;
  240. }
  241. int eliminar_vouchers_wget (char *ip, unsigned int rollo, char *usuario, char *clave)
  242. {
  243. char comando[512];
  244. unsigned int id=0;
  245. listarollos *rollos=NULL;
  246. /*Cargamos la lista de rollos*/
  247. rollos = cargar_lista_local_rollos ();
  248. /*Comprobamos que exista el rollo*/
  249. if (buscar_id_rollo (rollos, rollo, &id) != 0)
  250. {
  251. /*Liberamos la lista de rollos*/
  252. liberar_lista_rollos (rollos);
  253. return -1;
  254. }
  255. /*Liberamos la lista de rollos*/
  256. liberar_lista_rollos (rollos);
  257. rollos = NULL;
  258. /*Nos validamos en el portal de administración de Pfsense*/
  259. validar_usuario_wget (ip, usuario, clave);
  260. /*Formamos el comando*/
  261. sprintf (&comando[0],
  262. "wget -q -O %s --user-agent %s --load-cookies %s %s %s --referer http://%s/ http://%s/services_captiveportal_vouchers.php?act=del\\&id=%u",
  263. ARCHIVO_PAGINA, NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES,
  264. ARCHIVO_COOKIE, ip, ip, id);
  265. /*Ejecutamos el comando en el sistema*/
  266. system (&comando[0]);
  267. /*Eliminamos el archivo de la pagina ya que no la necesitamos*/
  268. remove (ARCHIVO_PAGINA);
  269. /*Eliminamos la cookie para finalizar la sesion*/
  270. remove (ARCHIVO_COOKIE);
  271. /*Cargamos la lista de rollos*/
  272. rollos = cargar_lista_local_rollos ();
  273. /*Eliminamos el archivo de vouchers*/
  274. eliminar_rollo_lista (&rollos, rollo);
  275. /*Liberamos la lista de rollos*/
  276. liberar_lista_rollos (rollos);
  277. rollos = NULL;
  278. return 0;
  279. }
  280. int obtener_sid_wget (char *ip, char *sid)
  281. {
  282. FILE *pagina=NULL;
  283. char comando[2048];
  284. char *auxiliar;
  285. int longitud;
  286. /*Indicamos que no hemos encontrado aun el sid*/
  287. int encontrado=-1;
  288. /*Formamos el comando*/
  289. sprintf (&comando[0],
  290. "wget -q -O %s --user-agent %s --load-cookies %s %s %s --referer http://%s/ http://%s/services_captiveportal_vouchers.php",
  291. ARCHIVO_PAGINA, NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES,
  292. ARCHIVO_COOKIE, ip, ip);
  293. /*Ejecutamos el comando en el sistema*/
  294. system (&comando[0]);
  295. /*Abrimos el archivo*/
  296. pagina = fopen (ARCHIVO_PAGINA, "r");
  297. /*Leemos todo el archivo buscando la linea que necesitamos*/
  298. while (fgets (&comando[0], 1024, pagina) != NULL)
  299. {
  300. /*Buscamos sid:*/
  301. auxiliar = strstr (&comando[0], "sid:");
  302. /*Comprobamos si lo hemos encontrado*/
  303. if (auxiliar != NULL)
  304. {
  305. /*Indicamos que lo encontramos*/
  306. encontrado = 0;
  307. /*Salimos del bucle*/
  308. break;
  309. }
  310. }
  311. /*Cerramos el archivo*/
  312. fclose (pagina);
  313. /*Eliminamos el archivo que ya es innecesario*/
  314. remove (ARCHIVO_PAGINA);
  315. /*Comprobamos si se encontro*/
  316. if (encontrado == 0)
  317. {
  318. /*Calculamos la longitud del sid*/
  319. longitud = strstr (auxiliar, "\"") - auxiliar;
  320. /*Copiamos el sid*/
  321. strncpy (sid, auxiliar, longitud);
  322. /*Indicamos el final de la cadena de caracteres*/
  323. *(sid + longitud) = '\0';
  324. }
  325. return encontrado;
  326. }
  327. int crear_vouchers_wget (char *ip, unsigned int rollo, unsigned int minutos,
  328. unsigned int numerovouchers, char *comentario,
  329. char *usuario, char *clave)
  330. {
  331. char comando[512];
  332. char sid[128];
  333. unsigned int id=0;
  334. listarollos *rollos=NULL;
  335. /*Cargamos la lista de rollos*/
  336. rollos = cargar_lista_local_rollos ();
  337. /*Comprobamos que no exista ya el rollo que intentamos crear*/
  338. if (buscar_id_rollo (rollos, rollo, &id) == 0)
  339. {
  340. /*Liberamos la lista de rollos*/
  341. liberar_lista_rollos (rollos);
  342. return -1;
  343. }
  344. /*Liberamos la lista de rollos*/
  345. liberar_lista_rollos (rollos);
  346. rollos = NULL;
  347. /*Nos validamos en el portal de administración de Pfsense*/
  348. validar_usuario_wget (ip, usuario, clave);
  349. /*Obtenemos el sid*/
  350. obtener_sid_wget (ip, &sid[0]);
  351. /*Lo codificamos para enviarlo por POST*/
  352. codificacion_url (&sid[0]);
  353. /*Formamos el comando*/
  354. sprintf (&comando[0],
  355. "wget -q -O %s --user-agent %s --load-cookies %s %s %s --post-data __csrf_magic=%s\\&number=%u\\&minutes=%u\\&count=%u\\&comment=%s\\&Submit=Save --referer http://%s/services_captiveportal_vouchers_edit.php http://%s/services_captiveportal_vouchers_edit.php",
  356. ARCHIVO_PAGINA, NAVEGADOR, ARCHIVO_COOKIE, OPCIONES_WGET_COOKIES,
  357. ARCHIVO_COOKIE, &sid[0], rollo, minutos, numerovouchers,
  358. comentario, ip, ip);
  359. /*Ejecutamos el comando en el sistema*/
  360. system (&comando[0]);
  361. /*Eliminamos el archivo que ya es innecesario*/
  362. remove (ARCHIVO_PAGINA);
  363. /*Eliminamos la cookie para finalizar la sesion*/
  364. remove (ARCHIVO_COOKIE);
  365. /*Cargamos la lista de rollos*/
  366. rollos = cargar_lista_local_rollos ();
  367. /*Agregamos el nuevo rollos*/
  368. agregar_rollo_lista (&rollos, rollo, minutos, numerovouchers, comentario);
  369. /*Guardamos la lista de rollos*/
  370. guardar_lista_local_rollos (rollos);
  371. /*Liberamos la lista de rollos*/
  372. liberar_lista_rollos (rollos);
  373. rollos = NULL;
  374. /*Cargamos la lista de rollos*/
  375. rollos = cargar_lista_local_rollos ();
  376. /*Obtenemos el id del rollo*/
  377. buscar_id_rollo (rollos, rollo, &id);
  378. /*Liberamos la lista de rollos*/
  379. liberar_lista_rollos (rollos);
  380. rollos = NULL;
  381. /*Descargamos los vouchers creados*/
  382. descargar_vouchers_wget (ip, id, usuario, clave);
  383. return 0;
  384. }
  385. int codificacion_url (char *cadena)
  386. {
  387. char auxiliar[128];
  388. char *recorrer;
  389. unsigned int i=0;
  390. /*Recorremos la cadena caracter a caracter*/
  391. for (recorrer=cadena; *recorrer != '\0'; recorrer++)
  392. {
  393. /*Comprobamos de que caracter se trata para codificarlo*/
  394. if (*recorrer == ':')
  395. {
  396. /*Codificamos el caracter*/
  397. auxiliar[i] = '%';
  398. i++;
  399. auxiliar[i] = '3';
  400. i++;
  401. auxiliar[i] = 'A';
  402. i++;
  403. }
  404. else if (*recorrer == '/')
  405. {
  406. /*Codificamos el caracter*/
  407. auxiliar[i] = '%';
  408. i++;
  409. auxiliar[i] = '2';
  410. i++;
  411. auxiliar[i] = 'F';
  412. i++;
  413. }
  414. else if (*recorrer == '.')
  415. {
  416. /*Codificamos el caracter*/
  417. auxiliar[i] = '%';
  418. i++;
  419. auxiliar[i] = '2';
  420. i++;
  421. auxiliar[i] = 'E';
  422. i++;
  423. }
  424. else if (*recorrer == ',')
  425. {
  426. /*Codificamos el caracter*/
  427. auxiliar[i] = '%';
  428. i++;
  429. auxiliar[i] = '2';
  430. i++;
  431. auxiliar[i] = 'C';
  432. i++;
  433. }
  434. else
  435. {
  436. /*Solo copiamos el caracter*/
  437. auxiliar[i] = *recorrer;
  438. i++;
  439. }
  440. }
  441. /*Colocamos el final de la cadena de caracteres*/
  442. auxiliar[i] = '\0';
  443. strcpy (cadena, &auxiliar[0]);
  444. return 0;
  445. }
  446. listarollos *cargar_lista_local_rollos ()
  447. {
  448. FILE *archivo=NULL;
  449. listarollos *primero=NULL, *nuevo=NULL, *auxiliar=NULL;
  450. rollovouchers registro;
  451. unsigned int id=0;
  452. /*Abrimos el archivo*/
  453. archivo = fopen (ARCHIVO_ROLLOS, "rb");
  454. /*Comprobamos si se pudo abrir*/
  455. if (archivo != NULL)
  456. {
  457. /*Leemos el archivo hasta el final*/
  458. while (!feof (archivo) )
  459. {
  460. /*Leemos un registro del archivo y comprobamos que no hubo errores*/
  461. if (fread (&registro, sizeof (rollovouchers), 1, archivo) != 1) break;
  462. /*Reservamos memoria para mantenerlo en memoria*/
  463. nuevo = (listarollos *) malloc (sizeof (listarollos) );
  464. /*Comprobamos que no haya ningun error*/
  465. if (nuevo == NULL) exit (-1);
  466. /*Copiamos los valores leidos*/
  467. nuevo -> id = id;
  468. id ++;
  469. nuevo -> rollo . rollo = registro . rollo;
  470. nuevo -> rollo . minutos = registro . minutos;
  471. nuevo -> rollo . numerovouchers = registro . numerovouchers;
  472. strcpy ( &(nuevo -> rollo . comentario[0]), &(registro . comentario [0]) );
  473. nuevo -> siguiente = NULL;
  474. /*Lo añadimos a la lista*/
  475. if (primero == NULL)
  476. {
  477. primero = nuevo;
  478. auxiliar = nuevo;
  479. nuevo = NULL;
  480. }
  481. else
  482. {
  483. /*Lo añadimos al final de la lista*/
  484. auxiliar -> siguiente = nuevo;
  485. auxiliar = nuevo;
  486. }
  487. }
  488. /*Cerramos el archivo*/
  489. fclose (archivo);
  490. }
  491. return primero;
  492. }
  493. int guardar_lista_local_rollos (listarollos *primero)
  494. {
  495. FILE *archivo=NULL;
  496. listarollos *auxiliar=NULL;
  497. rollovouchers registro;
  498. /*Eliminamos un posible archivo de respaldo de los rollos*/
  499. remove (ARCHIVO_RESPALDO_ROLLOS);
  500. /*Renombramos el archivo existente como copia de respaldo*/
  501. rename (ARCHIVO_ROLLOS, ARCHIVO_RESPALDO_ROLLOS);
  502. /*Abrimos el archivo*/
  503. archivo = fopen (ARCHIVO_ROLLOS, "wb");
  504. /*Comprobamos si se pudo abrir*/
  505. if (archivo != NULL)
  506. {
  507. /*Recorremos la lista de rollos*/
  508. for (auxiliar = primero; auxiliar != NULL; auxiliar = auxiliar -> siguiente )
  509. {
  510. /*Copiamos los valores a escribir*/
  511. registro . rollo = auxiliar -> rollo . rollo;
  512. registro . minutos = auxiliar -> rollo . minutos;
  513. registro . numerovouchers = auxiliar -> rollo . numerovouchers;
  514. strcpy (&(registro . comentario [0]), &(auxiliar -> rollo . comentario[0]) );
  515. /*Escribimos un registro del archivo*/
  516. fwrite (&registro, sizeof (rollovouchers), 1, archivo);
  517. }
  518. /*Cerramos el archivo*/
  519. fclose (archivo);
  520. /*Eliminamos el archivo de respaldo de los rollos*/
  521. remove (ARCHIVO_RESPALDO_ROLLOS);
  522. }
  523. else
  524. {
  525. /*Eliminamos el archivo de los rollos*/
  526. remove (ARCHIVO_ROLLOS);
  527. /*Renombramos el archivo de respaldo para recuperarlo*/
  528. rename (ARCHIVO_RESPALDO_ROLLOS, ARCHIVO_ROLLOS);
  529. }
  530. return 0;
  531. }
  532. int agregar_rollo_lista (listarollos **lista, unsigned int rollo, unsigned int minutos, unsigned int numerovouchers, char *comentario)
  533. {
  534. listarollos *auxiliar=NULL, *nuevo=NULL;
  535. /*Reservamos memoria para el nuevo rollo*/
  536. nuevo = (listarollos *) malloc (sizeof (listarollos) );
  537. /*Comprobamos que no haya ningun error*/
  538. if (nuevo == NULL) exit (-1);
  539. /*Copiamos los valores*/
  540. nuevo -> rollo . rollo = rollo;
  541. nuevo -> rollo . minutos = minutos;
  542. nuevo -> rollo . numerovouchers = numerovouchers;
  543. strcpy ( &(nuevo -> rollo . comentario[0]), comentario);
  544. nuevo -> siguiente = NULL;
  545. /*Comprobamos si la lista esta vacia*/
  546. if (*lista == NULL)
  547. {
  548. /*Al ser el primer elemento su numeración en la lista es la 0*/
  549. nuevo -> id = 0;
  550. /*Lo incluimos en la lista en la primera posición*/
  551. *lista = nuevo;
  552. }
  553. else
  554. {
  555. /*Buscamos el final de la lista*/
  556. auxiliar = *lista;
  557. while (auxiliar -> siguiente != NULL) auxiliar = auxiliar -> siguiente;
  558. /*Calculamos la numeración en lista del nuevo rollo*/
  559. nuevo -> id = auxiliar -> id + 1;
  560. /*Lo incluimos en la lista*/
  561. auxiliar -> siguiente = nuevo;
  562. }
  563. /*Guardamos la lista de rollos para mantener la lista de rollos actualziada
  564. a los cambios hechos*/
  565. guardar_lista_local_rollos (*lista);
  566. return 0;
  567. }
  568. int liberar_lista_rollos (listarollos *primero)
  569. {
  570. listarollos *recorrer, *liberar;
  571. /*Nos situamos al comienzo de la lista*/
  572. liberar = primero;
  573. /*Liberamos hasta que no queden elementos*/
  574. while (liberar != NULL)
  575. {
  576. /*Obtenemos el proximo elemento*/
  577. recorrer = liberar -> siguiente;
  578. /*Liberamos el actual*/
  579. free (liberar);
  580. /*Pasamos al siguiente*/
  581. liberar = recorrer;
  582. }
  583. return 0;
  584. }
  585. int buscar_id_rollo (listarollos *primero, unsigned int rollo, unsigned int *id)
  586. {
  587. int encontrado=-1;
  588. listarollos *auxiliar;
  589. /*Recorremos la lista*/
  590. for (auxiliar = primero; auxiliar != NULL; auxiliar = auxiliar -> siguiente)
  591. {
  592. /*Comprobamos si es el rollo que buscamos*/
  593. if (rollo == auxiliar -> rollo . rollo)
  594. {
  595. /*Asignamos el valor de posición en lista*/
  596. *id = auxiliar -> id;
  597. /*Indicamos que lo encontramos*/
  598. encontrado = 0;
  599. }
  600. }
  601. return encontrado;
  602. }
  603. int eliminar_rollo_lista (listarollos **lista, unsigned int rollo)
  604. {
  605. listarollos *recorrer=NULL, *liberar=NULL;
  606. char archivo[64];
  607. char archivorenombrado[64];
  608. /*Comprobamos si es el primer elemento*/
  609. if ( (*lista) -> rollo . rollo == rollo)
  610. {
  611. /*Apuntamos al elemento a liberar*/
  612. liberar = *lista;
  613. /*Quitamos el primer elemento*/
  614. *lista = liberar -> siguiente;
  615. /*Apuntamos al primer elemento que deberemos corregir la numeración*/
  616. recorrer = *lista;
  617. }
  618. else
  619. {
  620. /*Buscamos el rollo anterior al rollo a eliminar*/
  621. recorrer = *lista;
  622. while (recorrer -> siguiente -> rollo . rollo != rollo) recorrer = recorrer -> siguiente;
  623. /*Apuntamos al elemento a liberar*/
  624. liberar = recorrer -> siguiente;
  625. /*Lo sacamos de la lista*/
  626. recorrer -> siguiente = liberar -> siguiente;
  627. /*Apuntamos al primer elemento que deberemos corregir la numeración*/
  628. recorrer = recorrer -> siguiente;
  629. }
  630. /*Formamos la ruta al archivo del rollo*/
  631. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, liberar -> id, ".dat");
  632. /*Liberamos lamemoria*/
  633. free (liberar);
  634. /*Eliminamos el archivo del rollo*/
  635. remove (&archivo[0]);
  636. /*Recorremos todos los rollos de la lista a los que hay que corregirles la
  637. numeración para que sea continua en toda la lista*/
  638. while (recorrer != NULL)
  639. {
  640. /*Formamos la ruta al archivo del rollo*/
  641. sprintf (&archivo[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, recorrer -> id, ".dat");
  642. /*Corregimos la númeracion del rollo*/
  643. recorrer -> id --;
  644. /*Formamos la ruta al nuevo nombre del archivo del rollo*/
  645. sprintf (&archivorenombrado[0], "%s%u%s", PREFIJO_ARCHIVO_VOUCHERS, recorrer -> id, ".dat");
  646. /*Renombramos el archivo*/
  647. rename (&archivo[0], &archivorenombrado[0]);
  648. /*Pasamos al siguiente*/
  649. recorrer = recorrer -> siguiente;
  650. }
  651. /*Guardamos la lista de rollos para mantener la lista de rollos actualziada
  652. a los cambios hechos*/
  653. guardar_lista_local_rollos (*lista);
  654. return 0;
  655. }