command/commit
Added load of (local) files
author | Jan Wielemaker |
---|---|
Fri Mar 11 11:10:03 2011 +0100 | |
committer | Jan Wielemaker |
Fri Mar 11 11:10:03 2011 +0100 | |
commit | 43abee76d1ac01a8d9296906a8972985e8330509 |
tree | 464754555ea768d7ab3ee94d9a7db89d2549dcb3 |
parent | 7b144a58042bf5310a67c5c63a240028f8c12496 |
Diff style: patch stat
diff --git a/api/command.pl b/api/command.pl index cdd44c8..905f0d5 100644 --- a/api/command.pl +++ b/api/command.pl @@ -44,7 +44,7 @@ http:location(cmd, root(cmd), []). :- http_handler(cmd(ping), ping, []). -:- http_handler(cmd(load), load, []). +:- http_handler(cmd(load), load, [time_limit(infinite)]). %% ping(+Request) % diff --git a/client/cp-client.c b/client/cp-client.c index 1816d41..add0ec1 100644 --- a/client/cp-client.c +++ b/client/cp-client.c @@ -27,6 +27,7 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> +#include <ctype.h> char *program = NULL; char *prefix = ""; @@ -40,6 +41,10 @@ int debug = 0; #define FALSE 0 #define TRUE 1 +#define EOS 0 +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif static int isoption(const char *arg, const char *name, const char **val) @@ -69,6 +74,151 @@ file_base_name(const char *f) } +#ifdef O_HASDRIVES + +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') + +static int +IsAbsolutePath(const char *p) /* /d:/ */ +{ if ( p[0] == '/' && p[2] == ':' && isalpha(p[1]) && + (p[3] == '/' || p[3] == '\0') ) + succeed; + + if ( p[1] == ':' && isalpha(p[0]) && /* d:/ or d:\ */ + (IS_DIR_SEPARATOR(p[2]) || p[2] == '\0') ) + succeed; + +#ifdef O_HASSHARES + if ( (p[0] == '/' && p[1] == '/') || /* //host/share */ + (p[0] == '\\' && p[1] == '\\') ) /* \\host\share */ + succeed; +#endif + + fail; +} + +#else + +int +IsAbsolutePath(const char *p) /* /d:/ */ +{ return p[0] == '/'; +} + +#endif + + +static char * +canoniseFileName(char *path) +{ char *out = path, *in = path, *start = path; + char *osave[100]; + int osavep = 0; + +#ifdef O_HASDRIVES /* C: */ + if ( in[1] == ':' && isalpha(in[0]) ) + { in += 2; + + out = start = in; + } +#endif +#ifdef O_HASSHARES /* //host/ */ + if ( in[0] == '/' && in[1] == '/' && isAlpha(in[2]) ) + { char *s; + + for(s = in+3; *s && (isalnum(*s) || *s == '.'); s++) + ; + if ( *s == '/' ) + { in = out = s+1; + start = in-1; + } + } +#endif + + while( in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '/' ) + in += 3; + while( in[0] == '.' && in[1] == '/' ) + in += 2; + if ( in[0] == '/' ) + *out++ = '/'; + osave[osavep++] = out; + + while(*in) + { if (*in == '/') + { + again: + if ( *in ) + { while( in[1] == '/' ) /* delete multiple / */ + in++; + if ( in[1] == '.' ) + { if ( in[2] == '/' ) /* delete /./ */ + { in += 2; + goto again; + } + if ( in[2] == EOS ) /* delete trailing /. */ + { *out = EOS; + return path; + } + if ( in[2] == '.' && (in[3] == '/' || in[3] == EOS) ) + { if ( osavep > 0 ) /* delete /foo/../ */ + { out = osave[--osavep]; + in += 3; + if ( in[0] == EOS && out > start+1 ) + { out[-1] = EOS; /* delete trailing / */ + return path; + } + goto again; + } else if ( start[0] == '/' && out == start+1 ) + { in += 3; + goto again; + } + } + } + } + if ( *in ) + in++; + if ( out > path && out[-1] != '/' ) + *out++ = '/'; + osave[osavep++] = out; + } else + *out++ = *in++; + } + *out++ = *in++; + + return path; +} + + +char * +to_url(const char *data) +{ if ( strncmp(data, "http://", 7) == 0 || + strncmp(data, "https://", 8) == 0 ) + return strdup(data); + + if ( IsAbsolutePath(data) ) + { char *url = malloc(strlen(data)+strlen("file://")+1); + + strcpy(url, "file://"); + strcpy(url+strlen("file://"), data); + + return strdup(url); + } else + { char url[MAXPATHLEN]; + char *o; + + if ( !getcwd(url, sizeof(url)) ) + { perror("getcwd"); + exit(1); + } + + o = url+strlen(url); + if ( !(o>url && o[-1] == '/') ) + *o++ = '/'; + strcpy(o, data); + + return to_url(canoniseFileName(url)); + } +} + + static int usage(int code) { fprintf(stderr, "Usage: %s [option ...] command [arg ...]\n\n", program); @@ -179,12 +329,14 @@ ping() static int load_one(const char *data) { CURLcode rc; - const char *url = cmd_url("/cmd/load", A_STRING, "url", data, A_END); + char *dataurl = to_url(data); + const char *url = cmd_url("/cmd/load", A_STRING, "url", dataurl, A_END); if ( debug > 0 ) fprintf(stderr, "URL=%s\n", url); curl_easy_setopt(curl, CURLOPT_URL, url); rc = curl_easy_perform(curl); + free(dataurl); return curl_status(rc); }