/* -*- 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) */