/* Cataract - Static web photo gallery generator * Copyright (C) 2008 Tomas Bzatek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "gallery-utils.h" static char * strstr_exclude (const char *haystack, const char *needle, const char *exclude_when) { const char *src; char *found; src = haystack; while (src && strstr (src, needle)) { found = strstr (src, needle); /* skip if found 'exclude_when' at the same place as 'search' */ if (exclude_when && (found == strstr (haystack, exclude_when))) { src += strlen (exclude_when); continue; } else return found; } return NULL; } /* * str_replace: replace substring 'search' with a 'replace' string * - multiple occurrences of the string are replaced * - specify 'exclude_when' if you want to skip replace when a string found at the place of 'search' * - reallocates the original string */ void str_replace (char **dst, const char *search, const char *replace, const char *exclude_when) { #define REPLACE_MAX_LENGTH 32768 static char d[REPLACE_MAX_LENGTH]; char *src; char *found; int i; /* TODO: add range checking */ if (strstr (*dst, search) == NULL || strlen (*dst) == 0 || strlen (search) == 0 || strlen (replace) == 0) return; i = 0; src = *dst; while (strstr_exclude (src, search, exclude_when)) { found = strstr_exclude (src, search, exclude_when); /* copy the data between search string */ if (found > src) { memcpy (&d[i], src, found - src); i += found - src; } /* copy replace string instead */ memcpy (&d[i], replace, strlen (replace)); i += strlen (replace); src = found + strlen (search); } /* copy the rest */ if (src) { memcpy (&d[i], src, strlen (src)); i += strlen (src); } d[i] = 0x0; #ifdef __DEBUG_ALL__ printf ("str_replace('%s', '%s') = '%s' --> '%s'\n", search, replace, *dst, &d[0]); #endif /* return fixed string */ free (*dst); *dst = g_strdup (&d[0]); } /* * copy_file: copy file from src to dst */ gboolean copy_file (const char *src, const char *dst) { #define BUFFER_SIZE 65536 FILE *fin; FILE *fout; void *buffer; int size_r; fin = fopen (src, "r"); if (fin == NULL) { fprintf (stderr, "copy_file: error reading file \"%s\": %s\n", src, strerror (errno)); return FALSE; } fout = fopen (dst, "w"); if (fout == NULL) { fprintf (stderr, "copy_file: error writing to file \"%s\": %s\n", dst, strerror (errno)); fclose (fin); return FALSE; } buffer = malloc (BUFFER_SIZE); memset (buffer, 0, BUFFER_SIZE); size_r = BUFFER_SIZE; while ((! feof (fin)) && (size_r == BUFFER_SIZE)) { size_r = fread (buffer, 1, BUFFER_SIZE, fin); fwrite (buffer, 1, size_r, fout); } fclose (fout); fclose (fin); free (buffer); return TRUE; } /* * make_string: make string of 'substr' substrings * - returns newly allocated string */ char * make_string (const char* substr, const int count) { int i; char *s; s = malloc (strlen (substr) * count + 1); for (i = 0; i < count; i++) memcpy (s + (strlen (substr) * i), substr, strlen (substr)); s[strlen (substr) * count] = 0; return s; } /* * fix_entities: replace all invalid & entities with & * - returns newly allocated string */ void fix_entities (char **str) { static char d[REPLACE_MAX_LENGTH]; char *src; char *found; char *scan; int i; /* TODO: add range checking */ if (! *str || strstr (*str, "&") == NULL) return; i = 0; src = *str; while (strstr (src, "&")) { found = strstr (src, "&"); /* copy the data between search string */ memcpy (&d[i], src, found - src + 1); i += found - src + 1; /* scroll to next whitespace */ scan = found + 1; while (scan && ( (*scan >= 0x41 && *scan <= 0x5a) || (*scan >= 0x61 && *scan <= 0x7a) || /* A-Z, a-z */ (*scan >= 0x30 && *scan <= 0x39) || (*scan == 0x23) /* 0-9, # */ )) scan++; if (scan && (*scan == 0x3b)) { /* this is semicolon, correctly closed entity */ /* -- ignore */ } else { /* replace with & */ memcpy (&d[i], "amp;", 4); i += 4; } src = found + 1; } /* copy the rest */ if (src) { memcpy (&d[i], src, strlen (src)); i += strlen (src); } d[i] = 0x0; #ifdef __DEBUG_ALL__ printf ("fix_entities: '%s' --> '%s'\n", *str, &d[0]); #endif /* return fixed string */ free (*str); *str = g_strdup (&d[0]); }