diff options
Diffstat (limited to 'src/xml_ls.c')
-rw-r--r-- | src/xml_ls.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/xml_ls.c b/src/xml_ls.c new file mode 100644 index 0000000..c7341b9 --- /dev/null +++ b/src/xml_ls.c @@ -0,0 +1,204 @@ +/* $Id: xml_ls.c,v 1.17 2005/03/19 01:18:02 mgrouch Exp $ */ + +/* + +XMLStarlet: Command Line Toolkit to query/edit/check/transform XML documents + +Copyright (c) 2002-2004 Mikhail Grushinskiy. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +#include <config.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <libxml/xmlmemory.h> +#include <libxml/c14n.h> + +#include "xmlstar.h" +#include "escape.h" + +#if !HAVE_LSTAT +# if HAVE_STAT +# define lstat stat +# else +/* TODO: #ifdef out code that uses stat instead */ +# error "lstat() or stat() required" +# endif +#endif + +#ifndef S_ISLNK +# define S_ISLNK(m) 0 +#endif + +#ifndef S_ISSOCK +# define S_ISSOCK(m) 0 +#endif + +/** + * Print small help for command line options + */ +void +lsUsage(int argc, char **argv, exit_status status) +{ + extern void fprint_ls_usage(FILE* o, const char* argv0); + extern const char more_info[]; + FILE *o = (status == EXIT_SUCCESS)? stdout : stderr; + fprint_ls_usage(o, argv[0]); + fprintf(o, "%s", more_info); + exit(status); +} + + +const char * +get_file_type(mode_t mode) +{ + if (S_ISREG(mode)) return "f"; /* regular file */ + else if (S_ISDIR(mode)) return "d"; /* directory */ + else if (S_ISCHR(mode)) return "c"; /* character device */ + else if (S_ISBLK(mode)) return "b"; /* block device */ + else if (S_ISLNK(mode)) return "l"; /* symlink */ + else if (S_ISFIFO(mode)) return "p"; /* fifo */ + else if (S_ISSOCK(mode)) return "s"; /* socket */ + else return "u"; /* unknown */ +} + +const char * +get_file_perms(mode_t mode) +{ + int i; + static char perms[10]; + + strcpy(perms, "---------"); + + for(i=0; i < sizeof perms - 1; i+=3) + { + if(mode &(S_IRUSR>>i)) + perms[i+0] = 'r'; + + if(mode &(S_IWUSR>>i)) + perms[i+1] = 'w'; + + if(mode &(S_IXUSR>>i)) + perms[i+2] = 'x'; + } + +#ifdef S_ISUID + if((mode & S_ISUID)) + perms[2] = 's'; +#endif + +#ifdef S_ISGID + if((mode & S_ISGID)) + perms[5] = 's'; +#endif + +#ifdef S_ISVTX + if((mode & S_ISVTX)) + perms[8] = 't'; +#endif + + return(perms); +} + +int +xml_print_dir(const char* dir) +{ + DIR *dirp; + struct dirent *d; + struct stat stats; + int num_files = 0; + + if((dirp = opendir(dir)) == NULL) + return(-1); + + chdir(dir); + + while((d = readdir(dirp)) != NULL) + { + xmlChar *xml_str; + char atime[20]; + char mtime[20]; + int size_len; + + if ((d->d_name == NULL) || !strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + if(lstat(d->d_name, &stats) != 0) + { + fprintf(stderr, "couldn't stat: %s\n", d->d_name); + } + +#if defined (__MINGW32__) + /* somehow atime is -1 on Windows XP when the atime is in future */ + if (stats.st_atime < 0) stats.st_atime = 0; + /* somehow mtime is -1 on Windows XP when the mtime is in future */ + if (stats.st_mtime < 0) stats.st_mtime = 0; +#endif + + /* format time as per ISO 8601 */ + strftime(atime, sizeof atime, "%Y%m%dT%H%M%SZ", gmtime(&stats.st_atime)); + strftime(mtime, sizeof mtime, "%Y%m%dT%H%M%SZ", gmtime(&stats.st_mtime)); + + xml_str = xml_C11NNormalizeAttr((const xmlChar *) d->d_name); + printf("<%s p=\"%s\" a=\"%s\" m=\"%s\" s=\"", + get_file_type(stats.st_mode), get_file_perms(stats.st_mode), + atime, mtime); + size_len = printf("%lu", (unsigned long) stats.st_size); + printf("\"%.*s", 16-size_len, " "); + printf(" n=\"%s\"/>\n", xml_str); + num_files++; + xmlFree(xml_str); + + } /* end of for loop */ + + closedir(dirp); + return num_files; +} + +int +lsMain(int argc, char** argv) +{ + const char *dir = "."; + int files; + + if (argc == 3) { + if (strcmp(argv[2], "--help") == 0) + lsUsage(argc, argv, EXIT_SUCCESS); + else + dir = argv[2]; + } else if (argc > 3) { + lsUsage(argc, argv, EXIT_BAD_ARGS); + } + + printf("<dir>\n"); + files = xml_print_dir(dir); + printf("</dir>\n"); + return (files >= 0)? EXIT_SUCCESS : EXIT_FAILURE; +} + |