Store server capabilities and lockstore in urlinfo.

Attach urlinfo to fetch context prior to ripping ne_parse_uri.
Substitute /u->service/u->scheme/ everywhere to conform with modern usage.
Splint clean.

CVS patchset: 7543
CVS date: 2004/11/05 16:00:31
This commit is contained in:
jbj 2004-11-05 16:00:31 +00:00
parent 04724d83c3
commit 368da1cf26
6 changed files with 103 additions and 61 deletions

View File

@ -49,14 +49,15 @@ _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p)
}
/* =============================================================== */
/*@unchecked@*/
static ne_server_capabilities caps;
static int davFree(urlinfo u)
/*@globals internalState @*/
/*@modifies u, internalState @*/
{
if (u != NULL && u->sess != NULL) {
u->capabilities = _free(u->capabilities);
if (u->lockstore != NULL)
ne_lockstore_destroy(u->lockstore);
u->lockstore = NULL;
ne_session_destroy(u->sess);
u->sess = NULL;
}
@ -76,27 +77,34 @@ trust_all_server_certs(/*@unused@*/ void *userdata, /*@unused@*/ int failures,
static int davInit(const char * url, urlinfo * uret)
/*@globals internalState @*/
/*@modifies internalState @*/
/*@modifies *uret, internalState @*/
{
urlinfo u = NULL;
int xx;
/*@-globs@*/ /* FIX: h_errno annoyance. */
if (urlSplit(url, &u))
return -1; /* XXX error returns needed. */
/*@=globs@*/
if (u->urltype == URL_IS_HTTPS && u->sess == NULL) {
if (u->urltype == URL_IS_HTTPS && u->url != NULL && u->sess == NULL) {
ne_server_capabilities * capabilities;
/*@-noeffect@*/
ne_debug_init(stderr, 0);
ne_debug_init(stderr, 0); /* XXX oneshot? */
/*@=noeffect@*/
xx = ne_sock_init();
u->lock_store = ne_lockstore_create();
xx = ne_sock_init(); /* XXX oneshot? */
u->sess = ne_session_create(u->service, u->host, u->port);
if (!strcasecmp(u->service, "https"))
u->capabilities = capabilities = xcalloc(1, sizeof(*capabilities));
u->sess = ne_session_create(u->scheme, u->host, u->port);
/* XXX check that neon is ssl enabled. */
if (!strcasecmp(u->scheme, "https"))
ne_ssl_set_verify(u->sess, trust_all_server_certs, (char *)u->host);
ne_lockstore_register(u->lock_store, u->sess);
u->lockstore = ne_lockstore_create(); /* XXX oneshot? */
ne_lockstore_register(u->lockstore, u->sess);
ne_set_useragent(u->sess, PACKAGE "/" PACKAGE_VERSION);
}
@ -109,13 +117,13 @@ static int davInit(const char * url, urlinfo * uret)
static int davConnect(urlinfo u)
/*@globals internalState @*/
/*@modifies internalState @*/
/*@modifies u, internalState @*/
{
const char * path = NULL;
int rc;
(void) urlPath(u->url, &path);
rc = ne_options(u->sess, path, &caps);
rc = ne_options(u->sess, path, u->capabilities);
switch (rc) {
case NE_OK:
break;
@ -189,10 +197,12 @@ static void *fetch_create_item(/*@unused@*/ void *userdata, /*@unused@*/ const c
/* =============================================================== */
struct fetch_context_s {
/*@relnull@*/
struct fetch_resource_s **resrock;
/*@observer@*/
const char *uri;
unsigned int include_target; /* Include resource at href */
/*@refcounted@*/
urlinfo u;
int ac;
int nalloced;
ARGV_t av;
@ -203,7 +213,8 @@ struct fetch_context_s {
/*@null@*/
static void *fetch_destroy_context(/*@only@*/ /*@null@*/ struct fetch_context_s *ctx)
/*@modifies ctx @*/
/*@globals internalState @*/
/*@modifies ctx, internalState @*/
{
if (ctx == NULL)
return NULL;
@ -212,17 +223,29 @@ static void *fetch_destroy_context(/*@only@*/ /*@null@*/ struct fetch_context_s
ctx->modes = _free(ctx->modes);
ctx->sizes = _free(ctx->sizes);
ctx->mtimes = _free(ctx->mtimes);
ctx->u = urlFree(ctx->u, __FUNCTION__);
ctx->uri = _free(ctx->uri);
memset(ctx, 0, sizeof(*ctx));
ctx = _free(ctx);
return NULL;
}
/*@null@*/
static void *fetch_create_context(const char *uri)
/*@*/
/*@globals internalState @*/
/*@modifies internalState @*/
{
struct fetch_context_s * ctx = ne_calloc(sizeof(*ctx));
struct fetch_context_s * ctx;
urlinfo u;
/*@-globs@*/ /* FIX: h_errno annoyance. */
if (urlSplit(uri, &u))
return NULL;
/*@=globs@*/
ctx = ne_calloc(sizeof(*ctx));
ctx->uri = xstrdup(uri);
ctx->u = urlLink(u, __FUNCTION__);
return ctx;
}
@ -333,7 +356,6 @@ fprintf(stderr, "Skipping target resource.\n");
isexec = ne_propset_value(set, &fetch_props[2]);
checkin = ne_propset_value(set, &fetch_props[4]);
checkout = ne_propset_value(set, &fetch_props[5]);
if (clength == NULL)
status = ne_propset_status(set, &fetch_props[0]);
@ -484,9 +506,9 @@ static void display_ls_line(struct fetch_resource_s *res)
}
#endif
static int davFetch(urlinfo u, struct fetch_context_s * ctx)
static int davFetch(const urlinfo u, struct fetch_context_s * ctx)
/*@globals internalState @*/
/*@modifies *avp, internalState @*/
/*@modifies ctx, internalState @*/
{
const char * path = NULL;
int depth = 1; /* XXX passed arg? */
@ -560,15 +582,15 @@ fprintf(stderr, "*** argvAdd(%p,\"%s\")\n", &ctx->av, val);
switch (current->type) {
case resr_normal:
st_mode = S_IFREG;
break;
/*@switchbreak@*/ break;
case resr_collection:
st_mode = S_IFDIR;
break;
/*@switchbreak@*/ break;
case resr_reference:
case resr_error:
default:
st_mode = 0;
break;
/*@switchbreak@*/ break;
}
ctx->modes[ctx->ac] = st_mode;
ctx->sizes[ctx->ac] = current->size;
@ -577,20 +599,21 @@ fprintf(stderr, "*** argvAdd(%p,\"%s\")\n", &ctx->av, val);
current = fetch_destroy_item(current);
}
ctx->resrock = NULL; /* HACK: avoid leaving stack reference. */
return rc;
}
static int davNLST(struct fetch_context_s * ctx)
/*@globals internalState @*/
/*@modifies *avp, internalState @*/
/*@modifies ctx, internalState @*/
{
urlinfo u = NULL;
int rc;
int xx;
rc = davInit(ctx->uri, &u);
if (rc)
if (rc || u == NULL)
goto exit;
rc = davConnect(u);
@ -691,15 +714,19 @@ static const char * statstr(const struct stat * st,
static int dav_st_ino = 0xdead0000;
int davStat(const char * path, /*@out@*/ struct stat *st)
/*@globals dav_st_ino, h_errno, fileSystem, internalState @*/
/*@globals dav_st_ino, fileSystem, internalState @*/
/*@modifies *st, dav_st_ino, fileSystem, internalState @*/
{
struct fetch_context_s * ctx = NULL;
char buf[1024];
int rc = 0;
int rc = -1;
/* HACK: neon really wants collections with trailing '/' */
ctx = fetch_create_context(path);
if (ctx == NULL) {
/* HACK: errno = ??? */
goto exit;
}
rc = davNLST(ctx);
if (rc) {
/* HACK: errno = ??? */
@ -730,15 +757,19 @@ exit:
}
int davLstat(const char * path, /*@out@*/ struct stat *st)
/*@globals dav_st_ino, h_errno, fileSystem, internalState @*/
/*@globals dav_st_ino, fileSystem, internalState @*/
/*@modifies *st, dav_st_ino, fileSystem, internalState @*/
{
struct fetch_context_s * ctx = NULL;
char buf[1024];
int rc = 0;
int rc = -1;
/* HACK: neon really wants collections with trailing '/' */
ctx = fetch_create_context(path);
if (ctx == NULL) {
/* HACK: errno = ??? */
goto exit;
}
rc = davNLST(ctx);
if (rc) {
/* HACK: errno = ??? */
@ -989,9 +1020,15 @@ fprintf(stderr, "*** davOpendir(%s)\n", path);
/* Load DAV collection into argv. */
ctx = fetch_create_context(path);
rc = davNLST(ctx);
if (rc)
if (ctx == NULL) {
/* HACK: errno = ??? */
return NULL;
}
rc = davNLST(ctx);
if (rc) {
/* HACK: errno = ??? */
return NULL;
}
nb = 0;
ac = 0;

View File

@ -113,15 +113,15 @@ DIR * davOpendir(const char * path)
* stat(2) clone.
*/
int davStat(const char * path, /*@out@*/ struct stat * st)
/*@globals errno, h_errno, fileSystem, internalState @*/
/*@modifies *st, errno, fileSystem, internalState @*/;
/*@globals fileSystem, internalState @*/
/*@modifies *st, fileSystem, internalState @*/;
/**
* lstat(2) clone.
*/
int davLstat(const char * path, /*@out@*/ struct stat * st)
/*@globals errno, h_errno, fileSystem, internalState @*/
/*@modifies *st, errno, fileSystem, internalState @*/;
/*@globals fileSystem, internalState @*/
/*@modifies *st, fileSystem, internalState @*/;
#ifdef __cplusplus
}

View File

@ -1914,7 +1914,7 @@ int ufdClose( /*@only@*/ void * cookie)
/* XXX Why not (u->urltype == URL_IS_HTTP) ??? */
/* XXX Why not (u->urltype == URL_IS_HTTPS) ??? */
if (u->service != NULL && !strcmp(u->service, "http")) {
if (u->scheme != NULL && !strcmp(u->scheme, "http")) {
if (fd->wr_chunked) {
int rc;
/* XXX HTTP PUT requires terminating 0 length chunk. */

View File

@ -29,29 +29,35 @@ typedef /*@abstract@*/ /*@refcounted@*/ struct urlinfo_s * urlinfo;
*/
struct urlinfo_s {
/*@refs@*/ int nrefs; /*!< no. of references */
/*@owned@*/ /*@null@*/
/*@owned@*/ /*@relnull@*/
const char * url; /*!< copy of original url */
/*@owned@*/ /*@relnull@*/
const char * scheme; /*!< URI scheme. */
/*@owned@*/ /*@null@*/
const char * service;
const char * user; /*!< URI user. */
/*@owned@*/ /*@null@*/
const char * user;
const char * password; /*!< URI password. */
/*@owned@*/ /*@relnull@*/
const char * host; /*!< URI host. */
/*@owned@*/ /*@null@*/
const char * password;
/*@owned@*/ /*@null@*/
const char * host;
/*@owned@*/ /*@null@*/
const char * portstr;
const char * portstr; /*!< URI port string. */
/*@owned@*/ /*@null@*/
const char * proxyu; /*!< FTP: proxy user */
/*@owned@*/ /*@null@*/
const char * proxyh; /*!< FTP/HTTP: proxy host */
int proxyp; /*!< FTP/HTTP: proxy port */
int port;
int urltype;
int port; /*!< URI port. */
int urltype; /*!< URI type. */
FD_t ctrl; /*!< control channel */
FD_t data; /*!< per-xfer data channel */
void * sess;
void * lock_store;
/*@relnull@*/
void * capabilities; /*!< neon ne_server_capabilities ptr */
/*@relnull@*/
void * lockstore; /*!< neon ne_lock_store ptr */
/*@relnull@*/
void * sess; /*!< neon ne_session ptr */
int bufAlloced; /*!< sizeof I/O buffer */
/*@owned@*/
char * buf; /*!< I/O buffer */

View File

@ -87,7 +87,6 @@ static int ftsPrint(FTS * ftsp, FTSENT * fts)
return 0;
}
static int ftsOpts = 0;
static void ftsWalk(const char * path)

View File

@ -120,7 +120,7 @@ URLDBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file,
if (u->ctrl)
fprintf(stderr, _("warning: u %p ctrl %p nrefs != 0 (%s %s)\n"),
u, u->ctrl, (u->host ? u->host : ""),
(u->service ? u->service : ""));
(u->scheme ? u->scheme : ""));
/*@=usereleased@*/
}
if (u->data) {
@ -140,12 +140,12 @@ URLDBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file,
if (u->data)
fprintf(stderr, _("warning: u %p data %p nrefs != 0 (%s %s)\n"),
u, u->data, (u->host ? u->host : ""),
(u->service ? u->service : ""));
(u->scheme ? u->scheme : ""));
/*@=usereleased@*/
}
u->buf = _free(u->buf);
u->url = _free(u->url);
u->service = _free((void *)u->service);
u->scheme = _free((void *)u->scheme);
u->user = _free((void *)u->user);
u->password = _free((void *)u->password);
u->host = _free((void *)u->host);
@ -170,7 +170,7 @@ void urlFreeCache(void)
_("warning: _url_cache[%d] %p nrefs(%d) != 1 (%s %s)\n"),
i, _url_cache[i], _url_cache[i]->nrefs,
(_url_cache[i]->host ? _url_cache[i]->host : ""),
(_url_cache[i]->service ? _url_cache[i]->service : ""));
(_url_cache[i]->scheme ? _url_cache[i]->scheme : ""));
}
}
_url_cache = _free(_url_cache);
@ -218,7 +218,7 @@ static void urlFind(/*@null@*/ /*@in@*/ /*@out@*/ urlinfo * uret, int mustAsk)
* a) both items are not NULL and don't compare.
* b) either of the items is not NULL.
*/
if (urlStrcmp(u->service, ou->service))
if (urlStrcmp(u->scheme, ou->scheme))
continue;
if (urlStrcmp(u->host, ou->host))
continue;
@ -292,7 +292,7 @@ static void urlFind(/*@null@*/ /*@in@*/ /*@out@*/ urlinfo * uret, int mustAsk)
int port = strtol(proxy, &end, 0);
if (!(end && *end == '\0')) {
fprintf(stderr, _("error: %sport must be a number\n"),
(u->service ? u->service : ""));
(u->scheme ? u->scheme : ""));
return;
}
u->proxyp = port;
@ -318,7 +318,7 @@ static void urlFind(/*@null@*/ /*@in@*/ /*@out@*/ urlinfo * uret, int mustAsk)
int port = strtol(proxy, &end, 0);
if (!(end && *end == '\0')) {
fprintf(stderr, _("error: %sport must be a number\n"),
(u->service ? u->service : ""));
(u->scheme ? u->scheme : ""));
return;
}
u->proxyp = port;
@ -415,7 +415,7 @@ urltype urlPath(const char * url, const char ** pathp)
/*
* Split URL into components. The URL can look like
* service://user:password@host:port/path
* scheme://user:password@host:port/path
*/
/*@-bounds@*/
/*@-modfilesys@*/
@ -441,10 +441,10 @@ int urlSplit(const char * url, urlinfo *uret)
while (1) {
/* Point to end of next item */
while (*se && *se != '/') se++;
/* Item was service. Save service and go for the rest ...*/
/* Item was scheme. Save scheme and go for the rest ...*/
if (*se && (se != s) && se[-1] == ':' && se[0] == '/' && se[1] == '/') {
se[-1] = '\0';
u->service = xstrdup(s);
u->scheme = xstrdup(s);
se += 2; /* skip over "//" */
s = se++;
continue;
@ -491,10 +491,10 @@ int urlSplit(const char * url, urlinfo *uret)
}
u->host = xstrdup(f);
if (u->port < 0 && u->service != NULL) {
if (u->port < 0 && u->scheme != NULL) {
struct servent *serv;
/*@-multithreaded -moduncon @*/
serv = getservbyname(u->service, "tcp");
serv = getservbyname(u->scheme, "tcp");
/*@=multithreaded =moduncon @*/
if (serv != NULL)
u->port = ntohs(serv->s_port);