/* $Id$ Part of ClioPatria Author: Jan Wielemaker E-mail: J.Wielemaker@cs.vu.nl WWW: http://www.swi-prolog.org Copyright (C): 2011, VU University Amsterdam This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include char *program = NULL; char *prefix = ""; char *host = "localhost"; char *user = NULL; char *passwd = NULL; char *netrc = NULL; int port = 3020; CURL *curl = NULL; 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) { size_t len = strlen(name); if ( arg[0] == '-' && arg[1] == '-' && strncmp(&arg[2], name, len) == 0 && arg[2+len] == '=' ) { *val = &arg[3+len]; return TRUE; } return FALSE; } char * file_base_name(const char *f) { const char *base; for(base = f; *f; f++) { if (*f == '/') base = f+1; } return (char *)base; } #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); fprintf(stderr, "Options:\n"); fprintf(stderr, " --host=host Specify ClioPatria host (localhost)\n"); fprintf(stderr, " --port=port Specify ClioPatria port (3020)\n"); fprintf(stderr, " --user=user User name for authentication\n"); fprintf(stderr, " --passwd=passwd Password for authentication\n"); fprintf(stderr, " --netrc=netrc Use given netrc file\n"); fprintf(stderr, "\n"); fprintf(stderr, "Commands:\n"); fprintf(stderr, " ping Check that server is alive\n"); fprintf(stderr, " load file|url Load data from file or URL\n"); fprintf(stderr, " sparql query Run a SPARQL query\n"); return code; } typedef enum argtype { A_END = 0, A_STRING, A_LONG, } argtype; const char * cmd_url(const char *path, ...) { static char url[10240]; char *end = &url[sizeof(url)]; char *o = url; va_list args; int an = 0; va_start(args, path); o += snprintf(o, end-o, "http://%s:%d%s%s", host, port, prefix, path); for(;; an++) { argtype t = va_arg(args, argtype); switch(t) { case A_END: va_end(args); return url; case A_STRING: { const char *param = va_arg(args, const char*); const char *value = va_arg(args, const char*); char *e = curl_easy_escape(curl, value, 0); o += snprintf(o, end-o, "%s%s=", an == 0 ? "?" : "&", param); o += snprintf(o, end-o, "%s", e); curl_free(e); continue; } case A_LONG: { const char *param = va_arg(args, const char*); long value = va_arg(args, long); o += snprintf(o, end-o, "%s%s=", an == 0 ? "?" : "&", param); o += snprintf(o, end-o, "%ld", value); continue; } } } assert(0); return NULL; } static int curl_status(CURLcode rc) { long http_code; if ( rc ) fprintf(stderr, "%s: %s\n", program, curl_easy_strerror(rc)); rc = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); if ( debug ) fprintf(stderr, "HTTP CODE: %ld\n", http_code); if ( http_code != 200 ) rc = http_code / 100; /* system return codes is a byte */ return rc; } /******************************* * PING * *******************************/ static int ping() { CURLcode rc; curl_easy_setopt(curl, CURLOPT_URL, cmd_url("/cmd/ping", A_END)); rc = curl_easy_perform(curl); return curl_status(rc); } /******************************* * LOAD * *******************************/ static int load_one(const char *data) { CURLcode rc; 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); } static int load(int ac, const char **av) { int rc = 0; int i; for(i=0; rc == 0 && i 0 ) fprintf(stderr, "URL=%s\n", url); curl_easy_setopt(curl, CURLOPT_URL, url); rc = curl_easy_perform(curl); return curl_status(rc); } /******************************* * MAIN * *******************************/ int main(int argc, char **argv) { int i; int rc; const char *command; const char **cmdav; int cmdac; program = file_base_name(argv[0]); for(i=1; i