Commit 57a38985 57a389853f594e5532a44d74303cdee73d9292ac by Alain Magloire

AUTHORS ChangeLog THANKS lib/Makefile.am

Remove my name is THANKS, and put it as the current maitainer is AUTHORS.

 	lib/xmalloc.c lib/xstrdup.c lib/xstrtol.c lib/xstrtol.h
 	url/Makefile.am url/_cpystr.c url/chewurl.c url/test_url
 	url/url.c url/url.h url/url0.h url/url_imap.c url/url_mailto.c
 	url/url_mbox.c url/url_pop.c
First attempt to define the URL API.
1 parent 98aaefb7
The current maintainer Alain Magloire <alainm@rcsm.ece.mcgill.ca>
Jakob Kaivo <jkaivo@ndn.net>
Jeff Bailey <jbailey@gnu.org>
Sean 'Shaleh' Perry <shaleh@debian.org>
......
1999-12-01 Alain Magloire
* url/{_cpystr,chewurl,url,url_imap,url_mailto,url_mbox,url_pop}.c :
New files, first attempt to define the URL API.
* lib/Makefile.am: added xmalloc.c, xstrdup.c, xstrtol.{c,h}
* lib/{xmalloc,xstrdup,xstrtol}.c lib/xstrtol.h : New files
1999-11-21 Jeff Bailey <jbailey@nisa.net>
* doc/rfc*: Add. Standards followed should be included here.
......
......@@ -6,5 +6,4 @@ reporting problems, suggesting various improvements or submitting actual
code. Here is a list of these people. Help us keep it complete and exempt
of errors.
Alain Magloire <alainm@rcsm.ece.mcgill.ca>
Frank Belew <frb@wiw.org>
......
noinst_LIBRARIES = libmailutils.a
libmailutils_a_SOURCES = getopt.c getopt1.c md5.c getline.c
libmailutils_a_SOURCES = getopt.c getopt1.c md5.c getline.c xstrdup.c \
xstrtol.c xmalloc.c
noinst_HEADERS = getopt.h md5.h getline.h
noinst_HEADERS = getopt.h md5.h getline.h xstrtol.h
CFLAGS = -Wall -pedantic -g -DTESTING
......
/* xmalloc.c -- malloc with out of memory checking
Copyright (C) 1990-1997, 98, 99 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#if STDC_HEADERS
# include <stdlib.h>
#else
void *calloc ();
void *malloc ();
void *realloc ();
void free ();
#endif
#if ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
#else
# define textdomain(Domain)
# define _(Text) Text
#endif
#define N_(Text) Text
#include "error.h"
#include "xalloc.h"
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
#ifndef HAVE_DONE_WORKING_MALLOC_CHECK
you must run the autoconf test for a properly working malloc -- see malloc.m4
#endif
#ifndef HAVE_DONE_WORKING_REALLOC_CHECK
you must run the autoconf test for a properly working realloc -- see realloc.m4
#endif
/* Exit value when the requested amount of memory is not available.
The caller may set it to some other value. */
int xalloc_exit_failure = EXIT_FAILURE;
/* If non NULL, call this function when memory is exhausted. */
void (*xalloc_fail_func) () = 0;
/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message
before exiting when memory is exhausted. Goes through gettext. */
char *const xalloc_msg_memory_exhausted = N_("Memory exhausted");
static void
xalloc_fail (void)
{
if (xalloc_fail_func)
(*xalloc_fail_func) ();
error (xalloc_exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted));
}
/* Allocate N bytes of memory dynamically, with error checking. */
void *
xmalloc (size_t n)
{
void *p;
p = malloc (n);
if (p == 0)
xalloc_fail ();
return p;
}
/* Change the size of an allocated block of memory P to N bytes,
with error checking.
If P is NULL, run xmalloc. */
void *
xrealloc (void *p, size_t n)
{
p = realloc (p, n);
if (p == 0)
xalloc_fail ();
return p;
}
/* Allocate memory for N elements of S bytes, with error checking. */
void *
xcalloc (size_t n, size_t s)
{
void *p;
p = calloc (n, s);
if (p == 0)
xalloc_fail ();
return p;
}
/* xstrdup.c -- copy a string with out of memory checking
Copyright (C) 1990, 1996, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
# endif
#endif
#if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#include <sys/types.h>
char *xmalloc PARAMS ((size_t n));
/* Return a newly allocated copy of STRING. */
char *
xstrdup (const char *string)
{
return strcpy (xmalloc (strlen (string) + 1), string);
}
/* A more useful interface to strtol.
Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Jim Meyering. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#ifndef __strtol
# define __strtol strtol
# define __strtol_t long int
# define __xstrtol xstrtol
#endif
/* Some pre-ANSI implementations (e.g. SunOS 4)
need stderr defined if assertion checking is enabled. */
#include <stdio.h>
#if STDC_HEADERS
# include <stdlib.h>
#endif
#if HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
# ifndef strchr
# define strchr index
# endif
#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#if HAVE_LIMITS_H
# include <limits.h>
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* The extra casts work around common compiler bugs. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
It is necessary at least when t == time_t. */
#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
#define TYPE_MAXIMUM(t) (~ (t) 0 - TYPE_MINIMUM (t))
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
#include "xstrtol.h"
#ifndef strtol
long int strtol ();
#endif
#ifndef strtoul
unsigned long int strtoul ();
#endif
#ifndef strtoumax
uintmax_t strtoumax ();
#endif
static int
bkm_scale (__strtol_t *x, int scale_factor)
{
__strtol_t product = *x * scale_factor;
if (*x != product / scale_factor)
return 1;
*x = product;
return 0;
}
static int
bkm_scale_by_power (__strtol_t *x, int base, int power)
{
while (power--)
if (bkm_scale (x, base))
return 1;
return 0;
}
/* FIXME: comment. */
strtol_error
__xstrtol (const char *s, char **ptr, int strtol_base,
__strtol_t *val, const char *valid_suffixes)
{
char *t_ptr;
char **p;
__strtol_t tmp;
assert (0 <= strtol_base && strtol_base <= 36);
p = (ptr ? ptr : &t_ptr);
if (! TYPE_SIGNED (__strtol_t))
{
const char *q = s;
while (ISSPACE ((unsigned char) *q))
++q;
if (*q == '-')
return LONGINT_INVALID;
}
errno = 0;
tmp = __strtol (s, p, strtol_base);
if (errno != 0)
return LONGINT_OVERFLOW;
if (*p == s)
return LONGINT_INVALID;
/* Let valid_suffixes == NULL mean `allow any suffix'. */
/* FIXME: update all callers except the ones that allow suffixes
after the number, changing last parameter NULL to `""'. */
if (!valid_suffixes)
{
*val = tmp;
return LONGINT_OK;
}
if (**p != '\0')
{
int base = 1024;
int suffixes = 1;
int overflow;
if (!strchr (valid_suffixes, **p))
{
*val = tmp;
return LONGINT_INVALID_SUFFIX_CHAR;
}
if (strchr (valid_suffixes, '0'))
{
/* The ``valid suffix'' '0' is a special flag meaning that
an optional second suffix is allowed, which can change
the base, e.g. "100MD" for 100 megabytes decimal. */
switch (p[0][1])
{
case 'B':
suffixes++;
break;
case 'D':
base = 1000;
suffixes++;
break;
}
}
switch (**p)
{
case 'b':
overflow = bkm_scale (&tmp, 512);
break;
case 'B':
overflow = bkm_scale (&tmp, 1024);
break;
case 'c':
overflow = 0;
break;
case 'E': /* Exa */
overflow = bkm_scale_by_power (&tmp, base, 6);
break;
case 'G': /* Giga */
overflow = bkm_scale_by_power (&tmp, base, 3);
break;
case 'k': /* kilo */
overflow = bkm_scale_by_power (&tmp, base, 1);
break;
case 'M': /* Mega */
case 'm': /* 'm' is undocumented; for backward compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 2);
break;
case 'P': /* Peta */
overflow = bkm_scale_by_power (&tmp, base, 5);
break;
case 'T': /* Tera */
overflow = bkm_scale_by_power (&tmp, base, 4);
break;
case 'w':
overflow = bkm_scale (&tmp, 2);
break;
case 'Y': /* Yotta */
overflow = bkm_scale_by_power (&tmp, base, 8);
break;
case 'Z': /* Zetta */
overflow = bkm_scale_by_power (&tmp, base, 7);
break;
default:
*val = tmp;
return LONGINT_INVALID_SUFFIX_CHAR;
break;
}
if (overflow)
return LONGINT_OVERFLOW;
(*p) += suffixes;
}
*val = tmp;
return LONGINT_OK;
}
#ifdef TESTING_XSTRTO
# include <stdio.h>
# include "error.h"
char *program_name;
int
main (int argc, char** argv)
{
strtol_error s_err;
int i;
program_name = argv[0];
for (i=1; i<argc; i++)
{
char *p;
__strtol_t val;
s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
if (s_err == LONGINT_OK)
{
printf ("%s->%lu (%s)\n", argv[i], val, p);
}
else
{
STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
}
}
exit (0);
}
#endif /* TESTING_XSTRTO */
#ifndef XSTRTOL_H_
# define XSTRTOL_H_ 1
# if HAVE_INTTYPES_H
# include <inttypes.h> /* for uintmax_t */
# endif
# ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
# endif
# endif
# ifndef _STRTOL_ERROR
enum strtol_error
{
LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW
};
typedef enum strtol_error strtol_error;
# endif
# define _DECLARE_XSTRTOL(name, type) \
strtol_error \
name PARAMS ((const char *s, char **ptr, int base, \
type *val, const char *valid_suffixes));
_DECLARE_XSTRTOL (xstrtol, long int)
_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
# define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \
do \
{ \
switch ((Err)) \
{ \
case LONGINT_OK: \
abort (); \
\
case LONGINT_INVALID: \
error ((Exit_code), 0, "invalid %s `%s'", \
(Argument_type_string), (Str)); \
break; \
\
case LONGINT_INVALID_SUFFIX_CHAR: \
error ((Exit_code), 0, "invalid character following %s `%s'", \
(Argument_type_string), (Str)); \
break; \
\
case LONGINT_OVERFLOW: \
error ((Exit_code), 0, "%s `%s' too large", \
(Argument_type_string), (Str)); \
break; \
} \
} \
while (0)
# define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \
_STRTOL_ERROR (2, Str, Argument_type_string, Err)
# define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \
_STRTOL_ERROR (0, Str, Argument_type_string, Err)
#endif /* not XSTRTOL_H_ */
# Use automake to process this file -*-Makefile-*-
AUTOMAKE_OPTIONS = ../lib/ansi2knr
CFLAGS = -Wall -pedantic -g
include_HEADERS = url.h
noinst_HEADERS = url0.h
base_sources = _cpystr.c url.c url_imap.c url_mailto.c url_mbox.c url_pop.c
chewurl_SOURCES = $(base_sources) chewurl.c
EXTRA_DIST = test_url
LDADD = @ALLOCA@ @LIBOBJS@ @INTLLIBS@
datadir = $(prefix)/@DATADIRNAME@
localedir = $(datadir)/locale
INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"
#include <url0.h>
#include <string.h>
int
_cpystr (const char * src, char * dst, unsigned int size)
{
int len = src ? strlen (src) : 0 ;
if (dst == NULL || size == 0) {
return len;
}
if (len >= size) {
len = size - 1;
}
memcpy (dst, src, len);
dst[len] = '\0';
return len;
}
#include <url.h>
#include <stdio.h>
#include <string.h>
int
main (int argc, char ** argv)
{
int i;
int status;
long port;
url_t u;
char buffer[1024];
char str[1024];
while (fgets(str, sizeof (str), stdin) != NULL)
{
str[strlen(str) - 1] = '\0'; /* chop newline */
status = url_create (&u, str);
if (status == -1) {
printf("%s --> FAILED\n", str);
continue;
}
printf("%s --> SUCCESS\n", str);
url_get_scheme (u, buffer, sizeof (buffer));
printf("\tscheme %s\n", buffer);
url_get_user (u, buffer, sizeof (buffer));
printf("\tuser %s\n", buffer);
url_get_passwd (u, buffer, sizeof (buffer));
printf("\tpasswd %s\n", buffer);
url_pop_get_auth (u, buffer, sizeof (buffer));
printf("\tauth %s\n", buffer);
url_get_host (u, buffer, sizeof (buffer));
printf("\thost %s\n", buffer);
url_get_port (u, &port);
printf("\tport %d\n", port);
url_destroy (&u);
}
return 0;
}
pop://<user>;auth=<auth>@<host>:<port>
pop://rg@mailsrv.qualcomm.com
pop://rg;AUTH=+APOP@mail.eudora.com:8110
pop://baz;AUTH=SCRAM-MD5@foo.bar
#include <url.h>
#include <url0.h>
#include <string.h>
/* forward declaration */
static int get_scheme (const url_t, char *, unsigned int);
static int get_user (const url_t, char *, unsigned int);
static int get_passwd (const url_t, char *, unsigned int);
static int get_host (const url_t, char *, unsigned int);
static int get_port (const url_t, long *);
static int get_path (const url_t, char *, unsigned int);
static int get_query (const url_t, char *, unsigned int);
static int is_pop (const url_t);
static int is_imap (const url_t);
static struct _supported_scheme
{
char * scheme;
char len;
int (*_create) __P ((url_t *, const char *name));
void (*_destroy) __P ((url_t *));
} _supported_scheme[] = {
{ "mailto:", 7, url_mailto_create, url_mailto_destroy },
{ "pop://", 6, url_pop_create, url_pop_destroy },
{ "imap://", 7, url_imap_create, url_imap_destroy },
{ "file://", 7, url_mbox_create, url_mbox_destroy },
{ "/", 1, url_mbox_create, url_mbox_destroy }, /* hack ? */
{ NULL, (int (*)())NULL, (void (*)())NULL }
};
static int
get_scheme (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr (u->scheme, s, n);
}
static int
get_user (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr (u->user, s, n);
}
/* FIXME: We should not store passwd in clear, but rather
have a simple encoding, and decoding mechanism */
static int
get_passwd (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr (u->passwd, s, n);
}
static int
get_host (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr (u->host, s, n);
}
static int
get_port (const url_t u, long * p)
{
if (u == NULL) return -1;
return *p = u->port;
}
static int
get_path (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr(u->path, s, n);
}
static int
get_query (const url_t u, char * s, unsigned int n)
{
if (u == NULL) return -1;
return _cpystr(u->query, s, n);
}
static int
is_pop (const url_t u)
{
return u->type & URL_POP;
}
static int
is_imap (const url_t u)
{
return u->type & URL_IMAP;
}
static int
is_unixmbox (const url_t u)
{
return u->type & URL_MBOX;
}
int
(url_get_scheme) (const url_t url, char * scheme, unsigned int n)
{ return url->_get_scheme(url, scheme, n); }
int
(url_get_user) (const url_t url, char *user, unsigned int n)
{ return url->_get_user(url, user, n); }
int
(url_get_passwd) (const url_t url, char *passwd, unsigned int n)
{ return url->_get_passwd(url, passwd, n); }
int
(url_get_host) (const url_t url, char * host, unsigned int n)
{ return url->_get_host(url, host, n); }
int
(url_get_port) (const url_t url, long * port)
{ return url->_get_port(url, port); }
int
(url_get_path) (const url_t url, char *path, unsigned int n)
{ return url->_get_path(url, path, n); }
int
(url_get_query) (const url_t url, char *query, unsigned int n)
{ return url->_get_query(url, query, n); }
int
(url_is_pop) (const url_t url)
{ return (url->type & URL_POP); }
int
(url_is_imap) (const url_t url)
{ return (url->type & URL_IMAP); }
int
(url_is_unixmbox) (const url_t url)
{ return (url->type & URL_MBOX); }
int
url_create (url_t * url, const char * name)
{
int status = -1, i ;
/* sanity checks */
if (name == NULL || *name == '\0') {
return status;
}
/* scheme://scheme-specific-part */
for (i = 0; _supported_scheme[i].scheme; i++) {
if (strncasecmp (name, _supported_scheme[i].scheme, strlen(_supported_scheme[i].scheme)) == 0) {
status = 1;
break;
}
}
if (status == 1) {
status =_supported_scheme[i]._create(url, name);
if (status == 0) {
url_t u = *url;
if (u->_get_scheme == NULL) u->_get_scheme = get_scheme;
if (u->_get_user == NULL) u->_get_user = get_user;
if (u->_get_passwd == NULL) u->_get_passwd = get_passwd;
if (u->_get_host == NULL) u->_get_host = get_host;
if (u->_get_port == NULL) u->_get_port = get_port;
if (u->_get_path == NULL) u->_get_path = get_path;
if (u->_get_query == NULL) u->_get_query = get_query;
if (u->_is_pop == NULL) u->_is_pop = is_pop;
if (u->_is_imap == NULL) u->_is_imap = is_imap;
if (u->_is_unixmbox == NULL) u->_is_unixmbox = is_unixmbox;
if (u->_create == NULL) u->_create = _supported_scheme[i]._create;
if (u->_destroy == NULL) u->_destroy= _supported_scheme[i]._destroy;
}
}
return status;
}
void
url_destroy (url_t * url)
{
if (url && *url) {
url_t u = *url;
u->_destroy(url);
u = NULL;
}
}
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _URL_H
#define _URL_H 1
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*!__P */
/* forward declaration */
typedef struct _url
{
/* Data */
#define URL_POP ((int)1)
#define URL_IMAP (URL_POP << 1)
#define URL_MBOX (URL_IMAP << 1)
int type;
char *scheme;
char *user;
char *passwd; /* encoded ?? */
char *host;
long port;
char *path;
char *query;
void * data;
int (*_create) __P((struct _url **, const char *));
void (*_destroy) __P((struct _url **));
/* Methods */
int (*_get_scheme) __P ((const struct _url *, char *, unsigned int));
int (*_get_user) __P ((const struct _url *, char *, unsigned int));
int (*_get_passwd) __P ((const struct _url *, char *, unsigned int));
int (*_get_host) __P ((const struct _url *, char *, unsigned int));
int (*_get_port) __P ((const struct _url *, long *));
int (*_get_path) __P ((const struct _url *, char *, unsigned int));
int (*_get_query) __P ((const struct _url *, char *, unsigned int));
int (*_is_pop) __P ((const struct _url *));
int (*_is_imap) __P((const struct _url *));
int (*_is_unixmbox) __P((const struct _url *));
} * url_t;
extern int url_mailto_create __P ((url_t *, const char *name));
extern void url_mailto_destroy __P ((url_t *));
typedef struct _url_pop
{
/* we use the fields from url_t */
/* user, passwd, host, port */
char * auth;
int (*_get_auth) __P((const struct _url_pop *, char *, unsigned int));
} * url_pop_t;
extern int url_pop_create __P ((url_t *, const char *name));
extern void url_pop_destroy __P ((url_t *));
extern int url_imap_create __P ((url_t *, const char *name));
extern void url_imap_destroy __P ((url_t *));
extern int url_mbox_create __P ((url_t *, const char *name));
extern void url_mbox_destroy __P ((url_t *));
/*
struct _supported_scheme
{
char * scheme;
int (*_create) __P ((url_t *, const char *name));
void (*_destroy) __P ((url_t *));
};
*/
extern int url_create __P ((url_t *, const char *name));
extern void url_destroy __P ((url_t *));
#ifdef __GNUC__
#define INLINE __inline__
#else
#define INLINE
#endif
extern INLINE int url_get_scheme (const url_t url, char * pr, unsigned int n);
extern INLINE int url_get_user (const url_t url, char *user, unsigned int n);
extern INLINE int url_get_passwd (const url_t url, char * pwd, unsigned int n);
extern INLINE int url_get_host (const url_t url, char * host, unsigned int n);
extern INLINE int url_get_port (const url_t url, long * port);
extern INLINE int url_get_path (const url_t url, char * path, unsigned int n);
extern INLINE int url_get_query (const url_t url, char * query, unsigned int n);
extern INLINE int url_is_pop (const url_t url);
extern INLINE int url_is_imap(const url_t url);
extern INLINE int url_is_unixmbox(const url_t url);
/* pop*/
extern INLINE int url_pop_get_auth(const url_t u, char * a, unsigned int n);
#ifdef URL_MACROS
# define url_get_scheme(url, prot, n) url->_get_scheme(url, prot, n)
# define url_get_user(url, user, n) url->_get_user(url, user, n)
# define url_get_passwd(url, passwd, n) url->_get_passwd(url, passwd, n)
# define url_get_host(url, host, n) url->_get_host(url, host, n)
# define url_get_port(url, port) url->_get_port(url, port)
# define url_get_path(url, path, n) url->_get_path(url, path, n)
# define url_get_query(url, query, n) url->_get_query(url, query, n)
/* what we support so far */
# define url_is_pop(url) (url->type & URL_POP)
# define url_is_imap(url) (url->type & URL_IMAP)
# define url_is_unixmbox(url) (url->type & URL_MBOX)
/* pop */
# define url_pop_get_auth(url, auth, n) (((url_pop_t) \
(url->data))->_get_auth(url->data, auth, n))
#endif /* URL_MACROS */
#ifdef __cplusplus
}
#endif
#endif /* URL_H */
#ifndef _URL0_H
#define _URL0_H
#ifndef __P
# ifdef __STDC__
# define __P(x) x
# else
# define __P(x)
# endif
#endif
extern int _cpystr __P((const char * src, char * dst, unsigned int size));
#endif
#include <url.h>
void
url_imap_destroy (url_t * url)
{
return;
}
int
url_imap_create (url_t * u, const char * name)
{
return -1;
}
#include <url.h>
void
url_mailto_destroy (url_t * url)
{
return;
}
int
url_mailto_create (url_t *u, const char * name)
{
return -1;
}
#include <url.h>
void
url_mbox_destroy (url_t * url)
{
return;
}
int
url_mbox_create (url_t * u, const char * name)
{
return -1;
}
#include <url.h>
#include <url0.h>
#include <stdlib.h>
#include <string.h>
#define POP_PORT 110
static int get_auth (const url_pop_t up, char * s, unsigned int n);
static int
get_auth (const url_pop_t up, char * s, unsigned int n)
{
if (up == NULL) return -1;
return _cpystr (up->auth, s, n);
}
int url_pop_get_auth(const url_t url, char * auth, unsigned int n)
{
return ((url_pop_t) (url->data))->_get_auth(url->data, auth, n);
}
void
url_pop_destroy (url_t * url)
{
if (url && *url) {
url_t u = *url;
if (u->scheme) {
free (u->scheme);
}
if (u->user) {
free (u->user);
}
if (u->passwd) {
free (u->passwd);
}
if (u->host) {
free (u->host);
}
if (u->data) {
url_pop_t up = u->data;
if (up->auth) {
free (up->auth);
}
free (u->data);
}
free (u);
u = NULL;
}
}
/*
POP URL
pop://<user>;AUTH=<auth>@<host>:<port>
*/
int
url_pop_create (url_t * url, const char * name)
{
char * host_port, * index;
url_t u;
url_pop_t up;
/* reject the obvious */
if (name == NULL ||
strncmp ("pop://", name, 6) != 0 ||
(host_port = strchr (name, '@')) == NULL ||
strlen(name) < 9 /* 6(scheme)+1(user)+1(@)+1(host)*/) {
return -1;
}
/* do I need to decode url encoding '% hex hex' ? */
u = xcalloc(1, sizeof (*u));
u->data = up = xcalloc(1, sizeof(*up));
up->_get_auth = get_auth;
/* type */
u->type = URL_POP;
u->scheme = xstrdup ("pop://");
name += 6; /* pass the scheme */
/* looking for user;auth=auth-enc */
for (index = name; index != host_port; index++) {
if (*index == ';') { /* Auth ? */
break;
}
}
/* USER */
u->user = malloc(index - name + 1);
((char *)memcpy(u->user, name, index - name))[index - name] = '\0';
/* AUTH */
if ((host_port - index) <= 6) {
up->auth = malloc (1 + 1);
up->auth[0] = '*';
up->auth[1] = '\0';
} else {
index += 6; /* move pass AUTH= */
up->auth = malloc (host_port - index + 1);
((char *)memcpy (up->auth, index, host_port - index))[host_port - index] = '\0';
}
/* HOST:PORT */
index = strchr (++host_port, ':');
if (index == NULL) {
int len = strlen (host_port);
u->host = malloc (len + 1);
((char *)memcpy (u->host, host_port, len))[len] = '\0';
u->port = POP_PORT;
} else {
long p = strtol(index + 1, NULL, 10);
u->host = malloc (index - host_port + 1);
((char *)memcpy (u->host, host_port, index - host_port))[index - host_port]='\0';
u->port = (p == 0) ? POP_PORT : p;
}
*url = u;
return 0;
}