/* -*- c -*- * * ---------------------------------------------------------------------- * Directory and file flag utilities. * ---------------------------------------------------------------------- * * Copyright (c) 2002-2003 by PuhPuh * * This code is copyrighted property of the author. It can still * be used for any non-commercial purpose following conditions: * * 1) This copyright notice is not removed. * 2) Source code follows any distribution of the software * if possible. * 3) Copyright notice above is found in the documentation * of the distributed software. * * Any express or implied warranties are disclaimed. Author is * not liable for any direct or indirect damages caused by the use * of this software. * * ---------------------------------------------------------------------- * */ #include "ccincludes.h" #include "ccbuffer.h" #include "ccxstream.h" #include "ccxmltrans.h" static char *cc_xstream_file_name_to_string(const char *fn); static char *cc_xstream_path_name_to_components(const char *path); static char *cc_xstream_file_component_to_tag(const char *component, unsigned int level); static char *cc_xstream_file_name_to_string(const char *fn) { struct CcBufferRec buf[1]; char *r, c, *hlp2; const char *hlp; if (strchr(fn, '/') == NULL) { if (strcmp(fn, "") != 0) hlp = fn; else hlp = CC_XSTREAM_VERSION_STRING; } else { hlp = strrchr(fn, '/'); hlp++; } hlp2 = cc_xstrdup(hlp); hlp = hlp2; cc_buffer_init(buf); c = 0; for (/*NOTHING*/; *hlp; hlp++) { if ((*hlp == ':') || (*hlp == '.') || (*hlp == ',') || (*hlp == ';') || (*hlp == '(') || (*hlp == ')') || (*hlp == '-') || (*hlp == '[') || (*hlp == ']') || (*hlp == '{') || (*hlp == '}') || (*hlp == '&') || (*hlp == '%') || (*hlp == '?') || (*hlp == '#') || (*hlp == '=') || (*hlp == '*') || (*hlp == '@') || (*hlp == '!') || (*hlp == '&') || (*hlp == '+') || (*hlp == '\'')) { c = *hlp; cc_buffer_append(buf, &c, 1); } else if (isdigit(*hlp)) { c = *hlp; cc_buffer_append(buf, &c, 1); } else if (isalpha(*hlp)) { if (isalpha(c)) c = *hlp; else c = toupper(*hlp); cc_buffer_append(buf, &c, 1); } else { if ((c != ' ') && (c != 0)) { c = ' '; cc_buffer_append(buf, &c, 1); } } } r = cc_xmemdup(cc_buffer_ptr(buf), cc_buffer_len(buf)); cc_xfree(hlp2); cc_buffer_uninit(buf); return r; } static char *cc_xstream_file_component_to_tag(const char *component, unsigned int level) { struct CcBufferRec buf[1]; char nb[16], *r; char *xml_component; cc_buffer_init(buf); cc_buffer_append_string(buf, ""); xml_component = cc_xstream_xml_encode(component); cc_buffer_append_string(buf, xml_component); cc_xfree(xml_component); cc_buffer_append_string(buf, ""); r = cc_xmemdup(cc_buffer_ptr(buf), cc_buffer_len(buf)); cc_buffer_uninit(buf); return r; } static char *cc_xstream_path_name_to_components(const char *path) { const char *hlp; char *c1, *c2; char nb[16], *r; unsigned int count; struct CcBufferRec buf[1]; count = 0; cc_buffer_init(buf); while ((hlp = strchr(path, '/')) != NULL) { c1 = cc_xmemdup(path, hlp - path); path = hlp + 1; if ((strlen(c1) > 0) && (strcmp(c1, ".") != 0)) { c2 = cc_xstream_file_component_to_tag(c1, ++count); cc_buffer_append_string(buf, c2); cc_xfree(c2); } cc_xfree(c1); } if ((strlen(path) > 0) && (strcmp(path, ".") != 0)) { c2 = cc_xstream_file_component_to_tag(path, ++count); cc_buffer_append_string(buf, c2); cc_xfree(c2); } cc_buffer_prepend_string(buf, "\">"); snprintf(nb, sizeof (nb), "%u", count); cc_buffer_prepend_string(buf, nb); cc_buffer_prepend_string(buf, ""); r = cc_xmemdup(cc_buffer_ptr(buf), cc_buffer_len(buf)); cc_buffer_uninit(buf); return r; } CcStringList cc_xstream_string_list_add(CcStringList lst, const char *str) { CcStringList x; x = cc_xcalloc(1, sizeof (*x)); x->s = cc_xstrdup(str); x->next = lst; return x; } CcStringList cc_xstream_read_directory(const char *path) { DIR *dir; struct dirent *item; CcStringList r, x; r = NULL; dir = opendir(path); if (dir == NULL) return NULL; while ((item = readdir(dir)) != NULL) { if ((item->d_name[0] != '\0') && (strcmp(item->d_name, ".") != 0) && (strcmp(item->d_name, "..") != 0)) { x = cc_xcalloc(1, sizeof (*x)); x->s = cc_xstrdup(item->d_name); x->next = r; r = x; } } closedir(dir); return r; } char *cc_xstream_file_info(CcXstreamProg prog, const char *path, const char *relativepath) { struct stat st; struct CcBufferRec buf[1]; CC_UINT_64_TYPE_NAME t; char b[16], *r, *name, *rname, *tmp; int sr; r = NULL; if ((prog != NULL) && prog->follow_symlinks) sr = stat(path, &st); else sr = lstat(path, &st); if (sr == 0) { tmp = cc_xstream_file_name_to_string(relativepath); name = cc_xstream_xml_encode(tmp); cc_xfree(tmp); if (relativepath == NULL) rname = NULL; else if (strlen(relativepath) == 0) rname = cc_xstrdup(""); else rname = cc_xstream_path_name_to_components(relativepath); if (S_ISREG(st.st_mode)) { cc_buffer_init(buf); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, name); cc_buffer_append_string(buf, ""); if (rname != NULL) { cc_buffer_append_string(buf, rname); } cc_buffer_append_string(buf, "file"); cc_buffer_append_string(buf, ""); t = (CC_UINT_64_TYPE_NAME)(cc_xstream_file_size(path)); snprintf(b, sizeof (b), CC_UINT_64_PRINTF_FORMAT, t); cc_buffer_append_string(buf, b); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); r = cc_xmemdup(cc_buffer_ptr(buf), cc_buffer_len(buf)); cc_buffer_uninit(buf); } else if (S_ISDIR(st.st_mode)) { cc_buffer_init(buf); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, name); cc_buffer_append_string(buf, ""); if (rname != NULL) { cc_buffer_append_string(buf, rname); } cc_buffer_append_string(buf, "directory"); cc_buffer_append_string(buf, ""); cc_buffer_append_string(buf, ""); r = cc_xmemdup(cc_buffer_ptr(buf), cc_buffer_len(buf)); cc_buffer_uninit(buf); } cc_xfree(name); cc_xfree(rname); } return r; } int cc_xstream_path_is_directory(CcXstreamProg prog, const char *path) { struct stat st; if ((prog != NULL) && prog->follow_symlinks) return ((stat(path, &st) == 0) && (S_ISDIR(st.st_mode))); else return ((lstat(path, &st) == 0) && (S_ISDIR(st.st_mode))); } int cc_xstream_path_is_file(CcXstreamProg prog, const char *path) { struct stat st; if ((prog != NULL) && prog->follow_symlinks) return ((stat(path, &st) == 0) && (S_ISREG(st.st_mode))); else return ((lstat(path, &st) == 0) && (S_ISREG(st.st_mode))); } off_t cc_xstream_open_file_size(FILE *f) { #ifndef __CYGWIN__ struct stat st; if (fstat(fileno(f), &st) == 0) return st.st_size; return 0; #else off_t c, r; c = ftello(f); if (fseeko(f, 0, SEEK_END) != 0) return 0; r = ftello(f); fseeko(f, c, SEEK_SET); return r; #endif } off_t cc_xstream_file_size(const char *path) { #ifndef __CYGWIN__ struct stat st; if (stat(path, &st) == 0) return st.st_size; return 0; #else FILE *f; off_t r; f = fopen(path, "r"); if (f != NULL) { r = cc_xstream_open_file_size(f); fclose(f); return r; } return 0; #endif } /* eof (ccxfile.c) */