Revision 1801
| tags/nntpgrab-0.6.91/NNTPGrab.includes (revision 1801) | ||
|---|---|---|
| 1 |
automation |
|
| 2 |
base |
|
| 3 |
client/gui |
|
| 4 |
client/macosx |
|
| 5 |
client/web/module |
|
| 6 |
glue |
|
| 7 |
gui_base |
|
| 8 |
indexer |
|
| 9 |
nntpgrab_core |
|
| 10 |
plugins/decoder |
|
| 11 |
plugins/jsonrpc |
|
| 12 |
plugins/par2/par2cmdline |
|
| 13 |
plugins/par2 |
|
| 14 |
plugins/unpack/file-roller/copy-n-paste |
|
| 15 |
plugins/unpack/file-roller/nautilus |
|
| 16 |
plugins/unpack/file-roller/src |
|
| 17 |
plugins/unpack |
|
| 18 |
server_qt |
|
| 19 |
../deps/include |
|
| 20 |
../deps/include/gio-unix-2.0 |
|
| 21 |
../deps/include/gio-unix-2.0/gio |
|
| 22 |
../deps/include/glib-2.0 |
|
| 23 |
../deps/include/glib-2.0/gio |
|
| 24 |
../deps/include/glib-2.0/glib |
|
| 25 |
../deps/include/glib-2.0/gobject |
|
| 26 |
../deps/include/libsoup-2.4 |
|
| 27 |
../deps/include/libsoup-2.4/libsoup |
|
| 28 |
/usr/include |
|
| 29 |
/usr/include/libxml2 |
|
| 30 |
/usr/include/glib-2.0 |
|
| 31 |
/usr/include/glib-2.0/glib |
|
| 32 |
/usr/include/glib-2.0/gobject |
|
| 33 |
/usr/include/glib-2.0/gthread |
|
| 34 |
/usr/include/cairo |
|
| 35 |
/usr/include/pango-1.0 |
|
| 36 |
/usr/include/pango-1.0/pango |
|
| 37 |
/usr/include/gtk-2.0 |
|
| 38 |
/usr/include/gtk-2.0/gdk |
|
| 39 |
/usr/include/gtk-2.0/gdk-pixbuf |
|
| 40 |
/usr/include/gtk-2.0/gdk-pixbuf-xlib |
|
| 41 |
/usr/include/libgtkhtml-3.14 |
|
| 42 |
/usr/include/libgtkhtml-3.14/editor |
|
| 43 |
/usr/include/libgtkhtml-3.14/gtkhtml |
|
| 44 |
/usr/include/gnutls |
|
| 45 |
/usr/lib64/glib-2.0/include |
|
| 46 |
/usr/include/QtSolutions/ |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/decoder_thread.h (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
#ifndef _DECODER_THREAD_H_ |
|
| 20 |
#define _DECODER_THREAD_H_ |
|
| 21 |
|
|
| 22 |
#include "collections.h" |
|
| 23 |
#include "configuration.h" |
|
| 24 |
|
|
| 25 |
typedef struct _decoder_data {
|
|
| 26 |
NNTPCollection *collection; |
|
| 27 |
NNTPFile *file; |
|
| 28 |
//GThreadPool *poolPar2verify; |
|
| 29 |
//GThreadPool *poolPar2repair; |
|
| 30 |
//GThreadPool *poolUnpack; |
|
| 31 |
} DecoderData; |
|
| 32 |
|
|
| 33 |
void decoder_thread_initialize(Configuration *config); |
|
| 34 |
void decoder_thread_destroy(void); |
|
| 35 |
gboolean decoder_thread_start(void); |
|
| 36 |
gboolean decoder_thread_stop(void); |
|
| 37 |
void decoder_thread_push_task(DecoderData *task); |
|
| 38 |
|
|
| 39 |
#endif /* _DECODER_THREAD_H_ */ |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/queue_rawfile.h (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
#ifndef _QUEUE_RAWFILE_H_ |
|
| 20 |
#define _QUEUE_RAWFILE_H_ |
|
| 21 |
|
|
| 22 |
#include "collections.h" |
|
| 23 |
#include |
|
| 24 |
|
|
| 25 |
gboolean queue_rawfile_load(GList **queue_ret, char **errmsg); |
|
| 26 |
gboolean queue_rawfile_save(GList *queue, char **errmsg); |
|
| 27 |
|
|
| 28 |
#endif /* _QUEUE_RAWFILE_H_ */ |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/collection_alloc.c (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
#ifdef _MSC_VER |
|
| 20 |
#include "config.h.win32" |
|
| 21 |
#else |
|
| 22 |
#include "config.h" |
|
| 23 |
#endif |
|
| 24 |
|
|
| 25 |
#include |
|
| 26 |
#include "nntpgrab_types.h" |
|
| 27 |
#include "collections.h" |
|
| 28 |
#include "collection_alloc.h" |
|
| 29 |
|
|
| 30 |
NNTPFile * |
|
| 31 |
file_new(void) |
|
| 32 |
{
|
|
| 33 |
NNTPFile *file = g_slice_new0(NNTPFile); |
|
| 34 |
file_ref(file); |
|
| 35 |
return file; |
|
| 36 |
} |
|
| 37 |
|
|
| 38 |
void |
|
| 39 |
file_ref(NNTPFile *file) |
|
| 40 |
{
|
|
| 41 |
g_atomic_int_inc(&file->refcount); |
|
| 42 |
// g_print("file_ref: refcount = %i for subject %s\n", file->refcount, file->subject);
|
|
| 43 |
} |
|
| 44 |
|
|
| 45 |
void |
|
| 46 |
file_unref(NNTPFile *file) |
|
| 47 |
{
|
|
| 48 |
GList *groups; |
|
| 49 |
GList *parts; |
|
| 50 |
|
|
| 51 |
if (!g_atomic_int_dec_and_test(&file->refcount)) {
|
|
| 52 |
// g_print("file_unref: refcount = %i for subject %s\n", file->refcount, file->subject);
|
|
| 53 |
return; |
|
| 54 |
} |
|
| 55 |
|
|
| 56 |
// g_print("file_unref: refcount = %i for subject %s\n", file->refcount, file->subject);
|
|
| 57 |
// g_print("releasing file\n");
|
|
| 58 |
|
|
| 59 |
groups = file->groups; |
|
| 60 |
while (groups) {
|
|
| 61 |
g_free(groups->data); |
|
| 62 |
groups = g_list_next(groups); |
|
| 63 |
} |
|
| 64 |
|
|
| 65 |
g_list_free(file->groups); |
|
| 66 |
|
|
| 67 |
parts = file->parts; |
|
| 68 |
while (parts) {
|
|
| 69 |
g_slice_free(NNTPPart, parts->data); |
|
| 70 |
parts = g_list_next(parts); |
|
| 71 |
} |
|
| 72 |
|
|
| 73 |
g_list_free(file->parts); |
|
| 74 |
|
|
| 75 |
g_slice_free(NNTPFile, file); |
|
| 76 |
} |
|
| 77 |
|
|
| 78 |
NNTPCollection * |
|
| 79 |
collection_new(void) |
|
| 80 |
{
|
|
| 81 |
NNTPCollection *collection = g_slice_new0(NNTPCollection); |
|
| 82 |
g_static_mutex_init(&collection->mutex); |
|
| 83 |
collection_ref(collection); |
|
| 84 |
return collection; |
|
| 85 |
} |
|
| 86 |
|
|
| 87 |
void |
|
| 88 |
collection_ref(NNTPCollection *collection) |
|
| 89 |
{
|
|
| 90 |
g_atomic_int_inc(&collection->refcount); |
|
| 91 |
// g_print("collection_ref: refcount = %i for collection %s\n", collection->refcount, collection->collection_name);
|
|
| 92 |
} |
|
| 93 |
|
|
| 94 |
void |
|
| 95 |
collection_unref(NNTPCollection *collection) |
|
| 96 |
{
|
|
| 97 |
GList *files; |
|
| 98 |
|
|
| 99 |
if (!g_atomic_int_dec_and_test(&collection->refcount)) {
|
|
| 100 |
// g_print("collection_unref: refcount = %i for collection %s\n", collection->refcount, collection->collection_name);
|
|
| 101 |
return; |
|
| 102 |
} |
|
| 103 |
|
|
| 104 |
// g_print("collection_unref: refcount = %i for collection %s\n", collection->refcount, collection->collection_name);
|
|
| 105 |
// g_print("releasing collection\n");
|
|
| 106 |
|
|
| 107 |
files = collection->files; |
|
| 108 |
while (files) {
|
|
| 109 |
NNTPFile *file = (NNTPFile *) files->data; |
|
| 110 |
|
|
| 111 |
file_unref(file); |
|
| 112 |
|
|
| 113 |
files = g_list_next(files); |
|
| 114 |
} |
|
| 115 |
|
|
| 116 |
g_list_free(collection->files); |
|
| 117 |
g_list_free(collection->files_to_download); |
|
| 118 |
|
|
| 119 |
g_slice_free(NNTPCollection, collection); |
|
| 120 |
} |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/throttle.c (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
/* Parts of this file are taken from ProFTP's throttle.c */ |
|
| 20 |
|
|
| 21 |
#include |
|
| 22 |
#include |
|
| 23 |
#include |
|
| 24 |
#include |
|
| 25 |
#include |
|
| 26 |
#ifdef WIN32 |
|
| 27 |
#include |
|
| 28 |
#endif |
|
| 29 |
#include "nntpgrab.h" |
|
| 30 |
#include "nntpgrab_plugin.h" |
|
| 31 |
|
|
| 32 |
/* This allows a throttling process to be killed by the admin */ |
|
| 33 |
#ifndef WIN32 |
|
| 34 |
static void |
|
| 35 |
xfer_rate_sigmask(int block) |
|
| 36 |
{
|
|
| 37 |
static sigset_t sig_set; |
|
| 38 |
|
|
| 39 |
if (block) {
|
|
| 40 |
sigemptyset(&sig_set); |
|
| 41 |
|
|
| 42 |
sigaddset(&sig_set, SIGCHLD); |
|
| 43 |
sigaddset(&sig_set, SIGUSR1); |
|
| 44 |
sigaddset(&sig_set, SIGINT); |
|
| 45 |
sigaddset(&sig_set, SIGQUIT); |
|
| 46 |
#ifdef SIGIO |
|
| 47 |
sigaddset(&sig_set, SIGIO); |
|
| 48 |
#endif /* SIGIO */ |
|
| 49 |
#ifdef SIGBUS |
|
| 50 |
sigaddset(&sig_set, SIGBUS); |
|
| 51 |
#endif /* SIGBUS */ |
|
| 52 |
sigaddset(&sig_set, SIGHUP); |
|
| 53 |
|
|
| 54 |
while (sigprocmask(SIG_BLOCK, &sig_set, NULL) < 0) {
|
|
| 55 |
if (errno == EINTR) {
|
|
| 56 |
continue; |
|
| 57 |
} |
|
| 58 |
|
|
| 59 |
break; |
|
| 60 |
} |
|
| 61 |
} else {
|
|
| 62 |
while (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
|
|
| 63 |
if (errno == EINTR) {
|
|
| 64 |
continue; |
|
| 65 |
} |
|
| 66 |
|
|
| 67 |
break; |
|
| 68 |
} |
|
| 69 |
} |
|
| 70 |
} |
|
| 71 |
#endif |
|
| 72 |
|
|
| 73 |
/* Returns the difference, in milliseconds, between the given timeval and now */ |
|
| 74 |
static long |
|
| 75 |
xfer_rate_since(struct timeval *then) |
|
| 76 |
{
|
|
| 77 |
struct timeval now; |
|
| 78 |
gettimeofday(&now, NULL); |
|
| 79 |
|
|
| 80 |
return (((now.tv_sec - then->tv_sec) * 1000L) + ((now.tv_usec - then->tv_usec) / 1000L)); |
|
| 81 |
} |
|
| 82 |
|
|
| 83 |
void |
|
| 84 |
throttle_pause(struct timeval start_time, off_t xferlen, int max_bandwidth) |
|
| 85 |
{
|
|
| 86 |
long double xfer_rate_bps; |
|
| 87 |
long ideal = 0, elapsed = 0; |
|
| 88 |
|
|
| 89 |
/* Calculate the time interval since the transfer of data started. */ |
|
| 90 |
elapsed = xfer_rate_since(&start_time); |
|
| 91 |
xfer_rate_bps = max_bandwidth * 1024.0; |
|
| 92 |
|
|
| 93 |
ideal = (xferlen * 1000L) / xfer_rate_bps; |
|
| 94 |
|
|
| 95 |
if (ideal > elapsed) {
|
|
| 96 |
struct timeval tv; |
|
| 97 |
|
|
| 98 |
/* Setup for the select. We use select() instead of usleep() because it |
|
| 99 |
* seems to be far more portable across platforms. |
|
| 100 |
* |
|
| 101 |
* ideal and elapsed are in milleconds, but tv_usec will be microseconds, |
|
| 102 |
* so be sure to convert properly. |
|
| 103 |
*/ |
|
| 104 |
tv.tv_usec = (ideal - elapsed) * 1000; |
|
| 105 |
tv.tv_sec = tv.tv_usec / 1000000L; |
|
| 106 |
tv.tv_usec = tv.tv_usec % 1000000L; |
|
| 107 |
|
|
| 108 |
#if 0 |
|
| 109 |
ng_plugin_emit_log_msg(NULL, NG_LOG_LEVEL_DEBUG, "transferring too fast, delaying %ld sec%s, %ld usecs", |
|
| 110 |
(long int) tv.tv_sec, tv.tv_sec == 1 ? "" : "s", (long int) tv.tv_usec); |
|
| 111 |
#endif |
|
| 112 |
|
|
| 113 |
#ifdef WIN32 |
|
| 114 |
/* Stupid Win32 doesn't support the select() function with no sockets attached.. */ |
|
| 115 |
Sleep(ideal - elapsed); |
|
| 116 |
#else |
|
| 117 |
/* No interruptions, please... */ |
|
| 118 |
xfer_rate_sigmask(TRUE); |
|
| 119 |
|
|
| 120 |
if (select(0, NULL, NULL, NULL, &tv) < 0) {
|
|
| 121 |
ng_plugin_emit_log_msg(NULL, NG_LOG_LEVEL_WARNING, "warning: unable to throttle bandwidth: %s", strerror(errno)); |
|
| 122 |
} |
|
| 123 |
|
|
| 124 |
xfer_rate_sigmask(FALSE); |
|
| 125 |
#endif |
|
| 126 |
} |
|
| 127 |
|
|
| 128 |
return; |
|
| 129 |
} |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/strptime.c (revision 1801) | ||
|---|---|---|
| 1 |
/* Convert a string representation of time to a time value. |
|
| 2 |
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. |
|
| 3 |
This file is part of the GNU C Library. |
|
| 4 |
Contributed by Ulrich Drepper |
|
| 5 |
|
|
| 6 |
The GNU C Library is free software; you can redistribute it and/or |
|
| 7 |
modify it under the terms of the GNU Library General Public License as |
|
| 8 |
published by the Free Software Foundation; either version 2 of the |
|
| 9 |
License, or (at your option) any later version. |
|
| 10 |
|
|
| 11 |
The GNU C Library is distributed in the hope that it will be useful, |
|
| 12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 14 |
Library General Public License for more details. |
|
| 15 |
|
|
| 16 |
You should have received a copy of the GNU Library General Public |
|
| 17 |
License along with the GNU C Library; see the file COPYING.LIB. If not, |
|
| 18 |
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
| 19 |
Boston, MA 02111-1307, USA. */ |
|
| 20 |
|
|
| 21 |
/* XXX This version of the implementation is not really complete. |
|
| 22 |
Some of the fields cannot add information alone. But if seeing |
|
| 23 |
some of them in the same format (such as year, week and weekday) |
|
| 24 |
this is enough information for determining the date. */ |
|
| 25 |
|
|
| 26 |
#ifdef HAVE_CONFIG_H |
|
| 27 |
# include "config.h" |
|
| 28 |
#endif |
|
| 29 |
|
|
| 30 |
#ifdef WIN32 |
|
| 31 |
#define strncasecmp strnicmp |
|
| 32 |
#endif |
|
| 33 |
|
|
| 34 |
#include |
|
| 35 |
#include |
|
| 36 |
#include |
|
| 37 |
#include |
|
| 38 |
|
|
| 39 |
#ifdef _LIBC |
|
| 40 |
# include "../locale/localeinfo.h" |
|
| 41 |
#endif |
|
| 42 |
|
|
| 43 |
#include "strptime.h" |
|
| 44 |
|
|
| 45 |
#ifndef __P |
|
| 46 |
# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) |
|
| 47 |
# define __P(args) args |
|
| 48 |
# else |
|
| 49 |
# define __P(args) () |
|
| 50 |
# endif /* GCC. */ |
|
| 51 |
#endif /* Not __P. */ |
|
| 52 |
|
|
| 53 |
#if ! HAVE_LOCALTIME_R && ! defined localtime_r |
|
| 54 |
# ifdef _LIBC |
|
| 55 |
# define localtime_r __localtime_r |
|
| 56 |
# else |
|
| 57 |
/* Approximate localtime_r as best we can in its absence. */ |
|
| 58 |
# define localtime_r my_localtime_r |
|
| 59 |
static struct tm *localtime_r __P ((const time_t *, struct tm *)); |
|
| 60 |
static struct tm * |
|
| 61 |
localtime_r (t, tp) |
|
| 62 |
const time_t *t; |
|
| 63 |
struct tm *tp; |
|
| 64 |
{
|
|
| 65 |
struct tm *l = localtime (t); |
|
| 66 |
if (! l) |
|
| 67 |
return 0; |
|
| 68 |
*tp = *l; |
|
| 69 |
return tp; |
|
| 70 |
} |
|
| 71 |
# endif /* ! _LIBC */ |
|
| 72 |
#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ |
|
| 73 |
|
|
| 74 |
|
|
| 75 |
#define match_char(ch1, ch2) if (ch1 != ch2) return NULL |
|
| 76 |
#if defined __GNUC__ && __GNUC__ >= 2 |
|
| 77 |
# define match_string(cs1, s2) \ |
|
| 78 |
({ size_t len = strlen (cs1); \
|
|
| 79 |
int result = strncasecmp ((cs1), (s2), len) == 0; \ |
|
| 80 |
if (result) (s2) += len; \ |
|
| 81 |
result; }) |
|
| 82 |
#else |
|
| 83 |
/* Oh come on. Get a reasonable compiler. */ |
|
| 84 |
# define match_string(cs1, s2) \ |
|
| 85 |
(strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) |
|
| 86 |
#endif |
|
| 87 |
/* We intentionally do not use isdigit() for testing because this will |
|
| 88 |
lead to problems with the wide character version. */ |
|
| 89 |
#define get_number(from, to, n) \ |
|
| 90 |
do { \
|
|
| 91 |
int __n = n; \ |
|
| 92 |
val = 0; \ |
|
| 93 |
while (*rp == ' ') \ |
|
| 94 |
++rp; \ |
|
| 95 |
if (*rp < '0' || *rp > '9') \ |
|
| 96 |
return NULL; \ |
|
| 97 |
do { \
|
|
| 98 |
val *= 10; \ |
|
| 99 |
val += *rp++ - '0'; \ |
|
| 100 |
} while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ |
|
| 101 |
if (val < from || val > to) \ |
|
| 102 |
return NULL; \ |
|
| 103 |
} while (0) |
|
| 104 |
#ifdef _NL_CURRENT |
|
| 105 |
# define get_alt_number(from, to, n) \ |
|
| 106 |
({ \
|
|
| 107 |
__label__ do_normal; \ |
|
| 108 |
if (*decided != raw) \ |
|
| 109 |
{ \
|
|
| 110 |
const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ |
|
| 111 |
int __n = n; \ |
|
| 112 |
int any = 0; \ |
|
| 113 |
while (*rp == ' ') \ |
|
| 114 |
++rp; \ |
|
| 115 |
val = 0; \ |
|
| 116 |
do { \
|
|
| 117 |
val *= 10; \ |
|
| 118 |
while (*alts != '\0') \ |
|
| 119 |
{ \
|
|
| 120 |
size_t len = strlen (alts); \ |
|
| 121 |
if (strncasecmp (alts, rp, len) == 0) \ |
|
| 122 |
break; \ |
|
| 123 |
alts += len + 1; \ |
|
| 124 |
++val; \ |
|
| 125 |
} \ |
|
| 126 |
if (*alts == '\0') \ |
|
| 127 |
{ \
|
|
| 128 |
if (*decided == not && ! any) \ |
|
| 129 |
goto do_normal; \ |
|
| 130 |
/* If we haven't read anything it's an error. */ \ |
|
| 131 |
if (! any) \ |
|
| 132 |
return NULL; \ |
|
| 133 |
/* Correct the premature multiplication. */ \ |
|
| 134 |
val /= 10; \ |
|
| 135 |
break; \ |
|
| 136 |
} \ |
|
| 137 |
else \ |
|
| 138 |
*decided = loc; \ |
|
| 139 |
} while (--__n > 0 && val * 10 <= to); \ |
|
| 140 |
if (val < from || val > to) \ |
|
| 141 |
return NULL; \ |
|
| 142 |
} \ |
|
| 143 |
else \ |
|
| 144 |
{ \
|
|
| 145 |
do_normal: \ |
|
| 146 |
get_number (from, to, n); \ |
|
| 147 |
} \ |
|
| 148 |
0; \ |
|
| 149 |
}) |
|
| 150 |
#else |
|
| 151 |
# define get_alt_number(from, to, n) \ |
|
| 152 |
/* We don't have the alternate representation. */ \ |
|
| 153 |
get_number(from, to, n) |
|
| 154 |
#endif |
|
| 155 |
#define recursive(new_fmt) \ |
|
| 156 |
(*(new_fmt) != '\0' \ |
|
| 157 |
&& (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) |
|
| 158 |
|
|
| 159 |
|
|
| 160 |
#ifdef _LIBC |
|
| 161 |
/* This is defined in locale/C-time.c in the GNU libc. */ |
|
| 162 |
extern const struct locale_data _nl_C_LC_TIME; |
|
| 163 |
extern const unsigned short int __mon_yday[2][13]; |
|
| 164 |
|
|
| 165 |
# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) |
|
| 166 |
# define ab_weekday_name \ |
|
| 167 |
(&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) |
|
| 168 |
# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) |
|
| 169 |
# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) |
|
| 170 |
# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) |
|
| 171 |
# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) |
|
| 172 |
# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) |
|
| 173 |
# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) |
|
| 174 |
# define HERE_T_FMT_AMPM \ |
|
| 175 |
(_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) |
|
| 176 |
# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) |
|
| 177 |
|
|
| 178 |
# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) |
|
| 179 |
#else |
|
| 180 |
static char const weekday_name[][10] = |
|
| 181 |
{
|
|
| 182 |
"Sunday", "Monday", "Tuesday", "Wednesday", |
|
| 183 |
"Thursday", "Friday", "Saturday" |
|
| 184 |
}; |
|
| 185 |
static char const ab_weekday_name[][4] = |
|
| 186 |
{
|
|
| 187 |
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" |
|
| 188 |
}; |
|
| 189 |
static char const month_name[][10] = |
|
| 190 |
{
|
|
| 191 |
"January", "February", "March", "April", "May", "June", |
|
| 192 |
"July", "August", "September", "October", "November", "December" |
|
| 193 |
}; |
|
| 194 |
static char const ab_month_name[][4] = |
|
| 195 |
{
|
|
| 196 |
"Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|
| 197 |
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
|
| 198 |
}; |
|
| 199 |
# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" |
|
| 200 |
# define HERE_D_FMT "%m/%d/%y" |
|
| 201 |
# define HERE_AM_STR "AM" |
|
| 202 |
# define HERE_PM_STR "PM" |
|
| 203 |
# define HERE_T_FMT_AMPM "%I:%M:%S %p" |
|
| 204 |
# define HERE_T_FMT "%H:%M:%S" |
|
| 205 |
|
|
| 206 |
const unsigned short int __mon_yday[2][13] = |
|
| 207 |
{
|
|
| 208 |
/* Normal years. */ |
|
| 209 |
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
|
| 210 |
/* Leap years. */ |
|
| 211 |
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
|
| 212 |
}; |
|
| 213 |
#endif |
|
| 214 |
|
|
| 215 |
/* Status of lookup: do we use the locale data or the raw data? */ |
|
| 216 |
enum locale_status { not, loc, raw };
|
|
| 217 |
|
|
| 218 |
|
|
| 219 |
#ifndef __isleap |
|
| 220 |
/* Nonzero if YEAR is a leap year (every 4 years, |
|
| 221 |
except every 100th isn't, and every 400th is). */ |
|
| 222 |
# define __isleap(year) \ |
|
| 223 |
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) |
|
| 224 |
#endif |
|
| 225 |
|
|
| 226 |
/* Compute the day of the week. */ |
|
| 227 |
static void |
|
| 228 |
day_of_the_week (struct tm *tm) |
|
| 229 |
{
|
|
| 230 |
/* We know that January 1st 1970 was a Thursday (= 4). Compute the |
|
| 231 |
the difference between this data in the one on TM and so determine |
|
| 232 |
the weekday. */ |
|
| 233 |
int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); |
|
| 234 |
int wday = (-473 |
|
| 235 |
+ (365 * (tm->tm_year - 70)) |
|
| 236 |
+ (corr_year / 4) |
|
| 237 |
- ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) |
|
| 238 |
+ (((corr_year / 4) / 25) / 4) |
|
| 239 |
+ __mon_yday[0][tm->tm_mon] |
|
| 240 |
+ tm->tm_mday - 1); |
|
| 241 |
tm->tm_wday = ((wday % 7) + 7) % 7; |
|
| 242 |
} |
|
| 243 |
|
|
| 244 |
/* Compute the day of the year. */ |
|
| 245 |
static void |
|
| 246 |
day_of_the_year (struct tm *tm) |
|
| 247 |
{
|
|
| 248 |
tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] |
|
| 249 |
+ (tm->tm_mday - 1)); |
|
| 250 |
} |
|
| 251 |
|
|
| 252 |
static char * |
|
| 253 |
#ifdef _LIBC |
|
| 254 |
internal_function |
|
| 255 |
#endif |
|
| 256 |
strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, |
|
| 257 |
enum locale_status *decided, int era_cnt)); |
|
| 258 |
|
|
| 259 |
static char * |
|
| 260 |
#ifdef _LIBC |
|
| 261 |
internal_function |
|
| 262 |
#endif |
|
| 263 |
strptime_internal (rp, fmt, tm, decided, era_cnt) |
|
| 264 |
const char *rp; |
|
| 265 |
const char *fmt; |
|
| 266 |
struct tm *tm; |
|
| 267 |
enum locale_status *decided; |
|
| 268 |
int era_cnt; |
|
| 269 |
{
|
|
| 270 |
const char *rp_backup; |
|
| 271 |
int cnt; |
|
| 272 |
size_t val; |
|
| 273 |
int have_I, is_pm; |
|
| 274 |
int century, want_century; |
|
| 275 |
int want_era; |
|
| 276 |
int have_wday, want_xday; |
|
| 277 |
int have_yday; |
|
| 278 |
int have_mon, have_mday; |
|
| 279 |
#ifdef _NL_CURRENT |
|
| 280 |
size_t num_eras; |
|
| 281 |
#endif |
|
| 282 |
struct era_entry *era; |
|
| 283 |
|
|
| 284 |
have_I = is_pm = 0; |
|
| 285 |
century = -1; |
|
| 286 |
want_century = 0; |
|
| 287 |
want_era = 0; |
|
| 288 |
era = NULL; |
|
| 289 |
|
|
| 290 |
have_wday = want_xday = have_yday = have_mon = have_mday = 0; |
|
| 291 |
|
|
| 292 |
while (*fmt != '\0') |
|
| 293 |
{
|
|
| 294 |
/* A white space in the format string matches 0 more or white |
|
| 295 |
space in the input string. */ |
|
| 296 |
if (isspace (*fmt)) |
|
| 297 |
{
|
|
| 298 |
while (isspace (*rp)) |
|
| 299 |
++rp; |
|
| 300 |
++fmt; |
|
| 301 |
continue; |
|
| 302 |
} |
|
| 303 |
|
|
| 304 |
/* Any character but `%' must be matched by the same character |
|
| 305 |
in the iput string. */ |
|
| 306 |
if (*fmt != '%') |
|
| 307 |
{
|
|
| 308 |
match_char (*fmt++, *rp++); |
|
| 309 |
continue; |
|
| 310 |
} |
|
| 311 |
|
|
| 312 |
++fmt; |
|
| 313 |
#ifndef _NL_CURRENT |
|
| 314 |
/* We need this for handling the `E' modifier. */ |
|
| 315 |
start_over: |
|
| 316 |
#endif |
|
| 317 |
|
|
| 318 |
/* Make back up of current processing pointer. */ |
|
| 319 |
rp_backup = rp; |
|
| 320 |
|
|
| 321 |
switch (*fmt++) |
|
| 322 |
{
|
|
| 323 |
case '%': |
|
| 324 |
/* Match the `%' character itself. */ |
|
| 325 |
match_char ('%', *rp++);
|
|
| 326 |
break; |
|
| 327 |
case 'a': |
|
| 328 |
case 'A': |
|
| 329 |
/* Match day of week. */ |
|
| 330 |
for (cnt = 0; cnt < 7; ++cnt) |
|
| 331 |
{
|
|
| 332 |
#ifdef _NL_CURRENT |
|
| 333 |
if (*decided !=raw) |
|
| 334 |
{
|
|
| 335 |
if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) |
|
| 336 |
{
|
|
| 337 |
if (*decided == not |
|
| 338 |
&& strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), |
|
| 339 |
weekday_name[cnt])) |
|
| 340 |
*decided = loc; |
|
| 341 |
break; |
|
| 342 |
} |
|
| 343 |
if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) |
|
| 344 |
{
|
|
| 345 |
if (*decided == not |
|
| 346 |
&& strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), |
|
| 347 |
ab_weekday_name[cnt])) |
|
| 348 |
*decided = loc; |
|
| 349 |
break; |
|
| 350 |
} |
|
| 351 |
} |
|
| 352 |
#endif |
|
| 353 |
if (*decided != loc |
|
| 354 |
&& (match_string (weekday_name[cnt], rp) |
|
| 355 |
|| match_string (ab_weekday_name[cnt], rp))) |
|
| 356 |
{
|
|
| 357 |
*decided = raw; |
|
| 358 |
break; |
|
| 359 |
} |
|
| 360 |
} |
|
| 361 |
if (cnt == 7) |
|
| 362 |
/* Does not match a weekday name. */ |
|
| 363 |
return NULL; |
|
| 364 |
tm->tm_wday = cnt; |
|
| 365 |
have_wday = 1; |
|
| 366 |
break; |
|
| 367 |
case 'b': |
|
| 368 |
case 'B': |
|
| 369 |
case 'h': |
|
| 370 |
/* Match month name. */ |
|
| 371 |
for (cnt = 0; cnt < 12; ++cnt) |
|
| 372 |
{
|
|
| 373 |
#ifdef _NL_CURRENT |
|
| 374 |
if (*decided !=raw) |
|
| 375 |
{
|
|
| 376 |
if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) |
|
| 377 |
{
|
|
| 378 |
if (*decided == not |
|
| 379 |
&& strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), |
|
| 380 |
month_name[cnt])) |
|
| 381 |
*decided = loc; |
|
| 382 |
break; |
|
| 383 |
} |
|
| 384 |
if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) |
|
| 385 |
{
|
|
| 386 |
if (*decided == not |
|
| 387 |
&& strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), |
|
| 388 |
ab_month_name[cnt])) |
|
| 389 |
*decided = loc; |
|
| 390 |
break; |
|
| 391 |
} |
|
| 392 |
} |
|
| 393 |
#endif |
|
| 394 |
if (match_string (month_name[cnt], rp) |
|
| 395 |
|| match_string (ab_month_name[cnt], rp)) |
|
| 396 |
{
|
|
| 397 |
*decided = raw; |
|
| 398 |
break; |
|
| 399 |
} |
|
| 400 |
} |
|
| 401 |
if (cnt == 12) |
|
| 402 |
/* Does not match a month name. */ |
|
| 403 |
return NULL; |
|
| 404 |
tm->tm_mon = cnt; |
|
| 405 |
want_xday = 1; |
|
| 406 |
break; |
|
| 407 |
case 'c': |
|
| 408 |
/* Match locale's date and time format. */ |
|
| 409 |
#ifdef _NL_CURRENT |
|
| 410 |
if (*decided != raw) |
|
| 411 |
{
|
|
| 412 |
if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) |
|
| 413 |
{
|
|
| 414 |
if (*decided == loc) |
|
| 415 |
return NULL; |
|
| 416 |
else |
|
| 417 |
rp = rp_backup; |
|
| 418 |
} |
|
| 419 |
else |
|
| 420 |
{
|
|
| 421 |
if (*decided == not && |
|
| 422 |
strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) |
|
| 423 |
*decided = loc; |
|
| 424 |
want_xday = 1; |
|
| 425 |
break; |
|
| 426 |
} |
|
| 427 |
*decided = raw; |
|
| 428 |
} |
|
| 429 |
#endif |
|
| 430 |
if (!recursive (HERE_D_T_FMT)) |
|
| 431 |
return NULL; |
|
| 432 |
want_xday = 1; |
|
| 433 |
break; |
|
| 434 |
case 'C': |
|
| 435 |
/* Match century number. */ |
|
| 436 |
#ifdef _NL_CURRENT |
|
| 437 |
match_century: |
|
| 438 |
#endif |
|
| 439 |
get_number (0, 99, 2); |
|
| 440 |
century = val; |
|
| 441 |
want_xday = 1; |
|
| 442 |
break; |
|
| 443 |
case 'd': |
|
| 444 |
case 'e': |
|
| 445 |
/* Match day of month. */ |
|
| 446 |
get_number (1, 31, 2); |
|
| 447 |
tm->tm_mday = val; |
|
| 448 |
have_mday = 1; |
|
| 449 |
want_xday = 1; |
|
| 450 |
break; |
|
| 451 |
case 'F': |
|
| 452 |
if (!recursive ("%Y-%m-%d"))
|
|
| 453 |
return NULL; |
|
| 454 |
want_xday = 1; |
|
| 455 |
break; |
|
| 456 |
case 'x': |
|
| 457 |
#ifdef _NL_CURRENT |
|
| 458 |
if (*decided != raw) |
|
| 459 |
{
|
|
| 460 |
if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) |
|
| 461 |
{
|
|
| 462 |
if (*decided == loc) |
|
| 463 |
return NULL; |
|
| 464 |
else |
|
| 465 |
rp = rp_backup; |
|
| 466 |
} |
|
| 467 |
else |
|
| 468 |
{
|
|
| 469 |
if (*decided == not |
|
| 470 |
&& strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) |
|
| 471 |
*decided = loc; |
|
| 472 |
want_xday = 1; |
|
| 473 |
break; |
|
| 474 |
} |
|
| 475 |
*decided = raw; |
|
| 476 |
} |
|
| 477 |
#endif |
|
| 478 |
/* Fall through. */ |
|
| 479 |
case 'D': |
|
| 480 |
/* Match standard day format. */ |
|
| 481 |
if (!recursive (HERE_D_FMT)) |
|
| 482 |
return NULL; |
|
| 483 |
want_xday = 1; |
|
| 484 |
break; |
|
| 485 |
case 'k': |
|
| 486 |
case 'H': |
|
| 487 |
/* Match hour in 24-hour clock. */ |
|
| 488 |
get_number (0, 23, 2); |
|
| 489 |
tm->tm_hour = val; |
|
| 490 |
have_I = 0; |
|
| 491 |
break; |
|
| 492 |
case 'I': |
|
| 493 |
/* Match hour in 12-hour clock. */ |
|
| 494 |
get_number (1, 12, 2); |
|
| 495 |
tm->tm_hour = val % 12; |
|
| 496 |
have_I = 1; |
|
| 497 |
break; |
|
| 498 |
case 'j': |
|
| 499 |
/* Match day number of year. */ |
|
| 500 |
get_number (1, 366, 3); |
|
| 501 |
tm->tm_yday = val - 1; |
|
| 502 |
have_yday = 1; |
|
| 503 |
break; |
|
| 504 |
case 'm': |
|
| 505 |
/* Match number of month. */ |
|
| 506 |
get_number (1, 12, 2); |
|
| 507 |
tm->tm_mon = val - 1; |
|
| 508 |
have_mon = 1; |
|
| 509 |
want_xday = 1; |
|
| 510 |
break; |
|
| 511 |
case 'M': |
|
| 512 |
/* Match minute. */ |
|
| 513 |
get_number (0, 59, 2); |
|
| 514 |
tm->tm_min = val; |
|
| 515 |
break; |
|
| 516 |
case 'n': |
|
| 517 |
case 't': |
|
| 518 |
/* Match any white space. */ |
|
| 519 |
while (isspace (*rp)) |
|
| 520 |
++rp; |
|
| 521 |
break; |
|
| 522 |
case 'p': |
|
| 523 |
/* Match locale's equivalent of AM/PM. */ |
|
| 524 |
#ifdef _NL_CURRENT |
|
| 525 |
if (*decided != raw) |
|
| 526 |
{
|
|
| 527 |
if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) |
|
| 528 |
{
|
|
| 529 |
if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) |
|
| 530 |
*decided = loc; |
|
| 531 |
break; |
|
| 532 |
} |
|
| 533 |
if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) |
|
| 534 |
{
|
|
| 535 |
if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) |
|
| 536 |
*decided = loc; |
|
| 537 |
is_pm = 1; |
|
| 538 |
break; |
|
| 539 |
} |
|
| 540 |
*decided = raw; |
|
| 541 |
} |
|
| 542 |
#endif |
|
| 543 |
if (!match_string (HERE_AM_STR, rp)) {
|
|
| 544 |
if (match_string (HERE_PM_STR, rp)) {
|
|
| 545 |
is_pm = 1; |
|
| 546 |
} else {
|
|
| 547 |
return NULL; |
|
| 548 |
} |
|
| 549 |
} |
|
| 550 |
break; |
|
| 551 |
case 'r': |
|
| 552 |
#ifdef _NL_CURRENT |
|
| 553 |
if (*decided != raw) |
|
| 554 |
{
|
|
| 555 |
if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) |
|
| 556 |
{
|
|
| 557 |
if (*decided == loc) |
|
| 558 |
return NULL; |
|
| 559 |
else |
|
| 560 |
rp = rp_backup; |
|
| 561 |
} |
|
| 562 |
else |
|
| 563 |
{
|
|
| 564 |
if (*decided == not && |
|
| 565 |
strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), |
|
| 566 |
HERE_T_FMT_AMPM)) |
|
| 567 |
*decided = loc; |
|
| 568 |
break; |
|
| 569 |
} |
|
| 570 |
*decided = raw; |
|
| 571 |
} |
|
| 572 |
#endif |
|
| 573 |
if (!recursive (HERE_T_FMT_AMPM)) |
|
| 574 |
return NULL; |
|
| 575 |
break; |
|
| 576 |
case 'R': |
|
| 577 |
if (!recursive ("%H:%M"))
|
|
| 578 |
return NULL; |
|
| 579 |
break; |
|
| 580 |
case 's': |
|
| 581 |
{
|
|
| 582 |
/* The number of seconds may be very high so we cannot use |
|
| 583 |
the `get_number' macro. Instead read the number |
|
| 584 |
character for character and construct the result while |
|
| 585 |
doing this. */ |
|
| 586 |
time_t secs = 0; |
|
| 587 |
if (*rp < '0' || *rp > '9') |
|
| 588 |
/* We need at least one digit. */ |
|
| 589 |
return NULL; |
|
| 590 |
|
|
| 591 |
do |
|
| 592 |
{
|
|
| 593 |
secs *= 10; |
|
| 594 |
secs += *rp++ - '0'; |
|
| 595 |
} |
|
| 596 |
while (*rp >= '0' && *rp <= '9'); |
|
| 597 |
|
|
| 598 |
if (localtime_r (&secs, tm) == NULL) |
|
| 599 |
/* Error in function. */ |
|
| 600 |
return NULL; |
|
| 601 |
} |
|
| 602 |
break; |
|
| 603 |
case 'S': |
|
| 604 |
get_number (0, 61, 2); |
|
| 605 |
tm->tm_sec = val; |
|
| 606 |
break; |
|
| 607 |
case 'X': |
|
| 608 |
#ifdef _NL_CURRENT |
|
| 609 |
if (*decided != raw) |
|
| 610 |
{
|
|
| 611 |
if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) |
|
| 612 |
{
|
|
| 613 |
if (*decided == loc) |
|
| 614 |
return NULL; |
|
| 615 |
else |
|
| 616 |
rp = rp_backup; |
|
| 617 |
} |
|
| 618 |
else |
|
| 619 |
{
|
|
| 620 |
if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) |
|
| 621 |
*decided = loc; |
|
| 622 |
break; |
|
| 623 |
} |
|
| 624 |
*decided = raw; |
|
| 625 |
} |
|
| 626 |
#endif |
|
| 627 |
/* Fall through. */ |
|
| 628 |
case 'T': |
|
| 629 |
if (!recursive (HERE_T_FMT)) |
|
| 630 |
return NULL; |
|
| 631 |
break; |
|
| 632 |
case 'u': |
|
| 633 |
get_number (1, 7, 1); |
|
| 634 |
tm->tm_wday = val % 7; |
|
| 635 |
have_wday = 1; |
|
| 636 |
break; |
|
| 637 |
case 'g': |
|
| 638 |
get_number (0, 99, 2); |
|
| 639 |
/* XXX This cannot determine any field in TM. */ |
|
| 640 |
break; |
|
| 641 |
case 'G': |
|
| 642 |
if (*rp < '0' || *rp > '9') |
|
| 643 |
return NULL; |
|
| 644 |
/* XXX Ignore the number since we would need some more |
|
| 645 |
information to compute a real date. */ |
|
| 646 |
do |
|
| 647 |
++rp; |
|
| 648 |
while (*rp >= '0' && *rp <= '9'); |
|
| 649 |
break; |
|
| 650 |
case 'U': |
|
| 651 |
case 'V': |
|
| 652 |
case 'W': |
|
| 653 |
get_number (0, 53, 2); |
|
| 654 |
/* XXX This cannot determine any field in TM without some |
|
| 655 |
information. */ |
|
| 656 |
break; |
|
| 657 |
case 'w': |
|
| 658 |
/* Match number of weekday. */ |
|
| 659 |
get_number (0, 6, 1); |
|
| 660 |
tm->tm_wday = val; |
|
| 661 |
have_wday = 1; |
|
| 662 |
break; |
|
| 663 |
case 'y': |
|
| 664 |
#ifdef _NL_CURRENT |
|
| 665 |
match_year_in_century: |
|
| 666 |
#endif |
|
| 667 |
/* Match year within century. */ |
|
| 668 |
get_number (0, 99, 2); |
|
| 669 |
/* The "Year 2000: The Millennium Rollover" paper suggests that |
|
| 670 |
values in the range 69-99 refer to the twentieth century. */ |
|
| 671 |
tm->tm_year = val >= 69 ? val : val + 100; |
|
| 672 |
/* Indicate that we want to use the century, if specified. */ |
|
| 673 |
want_century = 1; |
|
| 674 |
want_xday = 1; |
|
| 675 |
break; |
|
| 676 |
case 'Y': |
|
| 677 |
/* Match year including century number. */ |
|
| 678 |
get_number (0, 9999, 4); |
|
| 679 |
tm->tm_year = val - 1900; |
|
| 680 |
want_century = 0; |
|
| 681 |
want_xday = 1; |
|
| 682 |
break; |
|
| 683 |
case 'Z': |
|
| 684 |
/* XXX How to handle this? */ |
|
| 685 |
break; |
|
| 686 |
case 'E': |
|
| 687 |
#ifdef _NL_CURRENT |
|
| 688 |
switch (*fmt++) |
|
| 689 |
{
|
|
| 690 |
case 'c': |
|
| 691 |
/* Match locale's alternate date and time format. */ |
|
| 692 |
if (*decided != raw) |
|
| 693 |
{
|
|
| 694 |
const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); |
|
| 695 |
|
|
| 696 |
if (*fmt == '\0') |
|
| 697 |
fmt = _NL_CURRENT (LC_TIME, D_T_FMT); |
|
| 698 |
|
|
| 699 |
if (!recursive (fmt)) |
|
| 700 |
{
|
|
| 701 |
if (*decided == loc) |
|
| 702 |
return NULL; |
|
| 703 |
else |
|
| 704 |
rp = rp_backup; |
|
| 705 |
} |
|
| 706 |
else |
|
| 707 |
{
|
|
| 708 |
if (strcmp (fmt, HERE_D_T_FMT)) |
|
| 709 |
*decided = loc; |
|
| 710 |
want_xday = 1; |
|
| 711 |
break; |
|
| 712 |
} |
|
| 713 |
*decided = raw; |
|
| 714 |
} |
|
| 715 |
/* The C locale has no era information, so use the |
|
| 716 |
normal representation. */ |
|
| 717 |
if (!recursive (HERE_D_T_FMT)) |
|
| 718 |
return NULL; |
|
| 719 |
want_xday = 1; |
|
| 720 |
break; |
|
| 721 |
case 'C': |
|
| 722 |
if (*decided != raw) |
|
| 723 |
{
|
|
| 724 |
if (era_cnt >= 0) |
|
| 725 |
{
|
|
| 726 |
era = _nl_select_era_entry (era_cnt); |
|
| 727 |
if (match_string (era->era_name, rp)) |
|
| 728 |
{
|
|
| 729 |
*decided = loc; |
|
| 730 |
break; |
|
| 731 |
} |
|
| 732 |
else |
|
| 733 |
return NULL; |
|
| 734 |
} |
|
| 735 |
else |
|
| 736 |
{
|
|
| 737 |
num_eras = _NL_CURRENT_WORD (LC_TIME, |
|
| 738 |
_NL_TIME_ERA_NUM_ENTRIES); |
|
| 739 |
for (era_cnt = 0; era_cnt < (int) num_eras; |
|
| 740 |
++era_cnt, rp = rp_backup) |
|
| 741 |
{
|
|
| 742 |
era = _nl_select_era_entry (era_cnt); |
|
| 743 |
if (match_string (era->era_name, rp)) |
|
| 744 |
{
|
|
| 745 |
*decided = loc; |
|
| 746 |
break; |
|
| 747 |
} |
|
| 748 |
} |
|
| 749 |
if (era_cnt == (int) num_eras) |
|
| 750 |
{
|
|
| 751 |
era_cnt = -1; |
|
| 752 |
if (*decided == loc) |
|
| 753 |
return NULL; |
|
| 754 |
} |
|
| 755 |
else |
|
| 756 |
break; |
|
| 757 |
} |
|
| 758 |
|
|
| 759 |
*decided = raw; |
|
| 760 |
} |
|
| 761 |
/* The C locale has no era information, so use the |
|
| 762 |
normal representation. */ |
|
| 763 |
goto match_century; |
|
| 764 |
case 'y': |
|
| 765 |
if (*decided == raw) |
|
| 766 |
goto match_year_in_century; |
|
| 767 |
|
|
| 768 |
get_number(0, 9999, 4); |
|
| 769 |
tm->tm_year = val; |
|
| 770 |
want_era = 1; |
|
| 771 |
want_xday = 1; |
|
| 772 |
break; |
|
| 773 |
case 'Y': |
|
| 774 |
if (*decided != raw) |
|
| 775 |
{
|
|
| 776 |
num_eras = _NL_CURRENT_WORD (LC_TIME, |
|
| 777 |
_NL_TIME_ERA_NUM_ENTRIES); |
|
| 778 |
for (era_cnt = 0; era_cnt < (int) num_eras; |
|
| 779 |
++era_cnt, rp = rp_backup) |
|
| 780 |
{
|
|
| 781 |
era = _nl_select_era_entry (era_cnt); |
|
| 782 |
if (recursive (era->era_format)) |
|
| 783 |
break; |
|
| 784 |
} |
|
| 785 |
if (era_cnt == (int) num_eras) |
|
| 786 |
{
|
|
| 787 |
era_cnt = -1; |
|
| 788 |
if (*decided == loc) |
|
| 789 |
return NULL; |
|
| 790 |
else |
|
| 791 |
rp = rp_backup; |
|
| 792 |
} |
|
| 793 |
else |
|
| 794 |
{
|
|
| 795 |
*decided = loc; |
|
| 796 |
era_cnt = -1; |
|
| 797 |
break; |
|
| 798 |
} |
|
| 799 |
|
|
| 800 |
*decided = raw; |
|
| 801 |
} |
|
| 802 |
get_number (0, 9999, 4); |
|
| 803 |
tm->tm_year = val - 1900; |
|
| 804 |
want_century = 0; |
|
| 805 |
want_xday = 1; |
|
| 806 |
break; |
|
| 807 |
case 'x': |
|
| 808 |
if (*decided != raw) |
|
| 809 |
{
|
|
| 810 |
const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); |
|
| 811 |
|
|
| 812 |
if (*fmt == '\0') |
|
| 813 |
fmt = _NL_CURRENT (LC_TIME, D_FMT); |
|
| 814 |
|
|
| 815 |
if (!recursive (fmt)) |
|
| 816 |
{
|
|
| 817 |
if (*decided == loc) |
|
| 818 |
return NULL; |
|
| 819 |
else |
|
| 820 |
rp = rp_backup; |
|
| 821 |
} |
|
| 822 |
else |
|
| 823 |
{
|
|
| 824 |
if (strcmp (fmt, HERE_D_FMT)) |
|
| 825 |
*decided = loc; |
|
| 826 |
break; |
|
| 827 |
} |
|
| 828 |
*decided = raw; |
|
| 829 |
} |
|
| 830 |
if (!recursive (HERE_D_FMT)) |
|
| 831 |
return NULL; |
|
| 832 |
break; |
|
| 833 |
case 'X': |
|
| 834 |
if (*decided != raw) |
|
| 835 |
{
|
|
| 836 |
const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); |
|
| 837 |
|
|
| 838 |
if (*fmt == '\0') |
|
| 839 |
fmt = _NL_CURRENT (LC_TIME, T_FMT); |
|
| 840 |
|
|
| 841 |
if (!recursive (fmt)) |
|
| 842 |
{
|
|
| 843 |
if (*decided == loc) |
|
| 844 |
return NULL; |
|
| 845 |
else |
|
| 846 |
rp = rp_backup; |
|
| 847 |
} |
|
| 848 |
else |
|
| 849 |
{
|
|
| 850 |
if (strcmp (fmt, HERE_T_FMT)) |
|
| 851 |
*decided = loc; |
|
| 852 |
break; |
|
| 853 |
} |
|
| 854 |
*decided = raw; |
|
| 855 |
} |
|
| 856 |
if (!recursive (HERE_T_FMT)) |
|
| 857 |
return NULL; |
|
| 858 |
break; |
|
| 859 |
default: |
|
| 860 |
return NULL; |
|
| 861 |
} |
|
| 862 |
break; |
|
| 863 |
#else |
|
| 864 |
/* We have no information about the era format. Just use |
|
| 865 |
the normal format. */ |
|
| 866 |
if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' |
|
| 867 |
&& *fmt != 'x' && *fmt != 'X') |
|
| 868 |
/* This is an illegal format. */ |
|
| 869 |
return NULL; |
|
| 870 |
|
|
| 871 |
goto start_over; |
|
| 872 |
#endif |
|
| 873 |
case 'O': |
|
| 874 |
switch (*fmt++) |
|
| 875 |
{
|
|
| 876 |
case 'd': |
|
| 877 |
case 'e': |
|
| 878 |
/* Match day of month using alternate numeric symbols. */ |
|
| 879 |
get_alt_number (1, 31, 2); |
|
| 880 |
tm->tm_mday = val; |
|
| 881 |
have_mday = 1; |
|
| 882 |
want_xday = 1; |
|
| 883 |
break; |
|
| 884 |
case 'H': |
|
| 885 |
/* Match hour in 24-hour clock using alternate numeric |
|
| 886 |
symbols. */ |
|
| 887 |
get_alt_number (0, 23, 2); |
|
| 888 |
tm->tm_hour = val; |
|
| 889 |
have_I = 0; |
|
| 890 |
break; |
|
| 891 |
case 'I': |
|
| 892 |
/* Match hour in 12-hour clock using alternate numeric |
|
| 893 |
symbols. */ |
|
| 894 |
get_alt_number (1, 12, 2); |
|
| 895 |
tm->tm_hour = val - 1; |
|
| 896 |
have_I = 1; |
|
| 897 |
break; |
|
| 898 |
case 'm': |
|
| 899 |
/* Match month using alternate numeric symbols. */ |
|
| 900 |
get_alt_number (1, 12, 2); |
|
| 901 |
tm->tm_mon = val - 1; |
|
| 902 |
have_mon = 1; |
|
| 903 |
want_xday = 1; |
|
| 904 |
break; |
|
| 905 |
case 'M': |
|
| 906 |
/* Match minutes using alternate numeric symbols. */ |
|
| 907 |
get_alt_number (0, 59, 2); |
|
| 908 |
tm->tm_min = val; |
|
| 909 |
break; |
|
| 910 |
case 'S': |
|
| 911 |
/* Match seconds using alternate numeric symbols. */ |
|
| 912 |
get_alt_number (0, 61, 2); |
|
| 913 |
tm->tm_sec = val; |
|
| 914 |
break; |
|
| 915 |
case 'U': |
|
| 916 |
case 'V': |
|
| 917 |
case 'W': |
|
| 918 |
get_alt_number (0, 53, 2); |
|
| 919 |
/* XXX This cannot determine any field in TM without |
|
| 920 |
further information. */ |
|
| 921 |
break; |
|
| 922 |
case 'w': |
|
| 923 |
/* Match number of weekday using alternate numeric symbols. */ |
|
| 924 |
get_alt_number (0, 6, 1); |
|
| 925 |
tm->tm_wday = val; |
|
| 926 |
have_wday = 1; |
|
| 927 |
break; |
|
| 928 |
case 'y': |
|
| 929 |
/* Match year within century using alternate numeric symbols. */ |
|
| 930 |
get_alt_number (0, 99, 2); |
|
| 931 |
tm->tm_year = val >= 69 ? val : val + 100; |
|
| 932 |
want_xday = 1; |
|
| 933 |
break; |
|
| 934 |
default: |
|
| 935 |
return NULL; |
|
| 936 |
} |
|
| 937 |
break; |
|
| 938 |
default: |
|
| 939 |
return NULL; |
|
| 940 |
} |
|
| 941 |
} |
|
| 942 |
|
|
| 943 |
if (have_I && is_pm) |
|
| 944 |
tm->tm_hour += 12; |
|
| 945 |
|
|
| 946 |
if (century != -1) |
|
| 947 |
{
|
|
| 948 |
if (want_century) |
|
| 949 |
tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; |
|
| 950 |
else |
|
| 951 |
/* Only the century, but not the year. Strange, but so be it. */ |
|
| 952 |
tm->tm_year = (century - 19) * 100; |
|
| 953 |
} |
|
| 954 |
|
|
| 955 |
#ifdef _NL_CURRENT |
|
| 956 |
if (era_cnt != -1) |
|
| 957 |
{
|
|
| 958 |
era = _nl_select_era_entry(era_cnt); |
|
| 959 |
if (want_era) |
|
| 960 |
tm->tm_year = (era->start_date[0] |
|
| 961 |
+ ((tm->tm_year - era->offset) |
|
| 962 |
* era->absolute_direction)); |
|
| 963 |
else |
|
| 964 |
/* Era start year assumed. */ |
|
| 965 |
tm->tm_year = era->start_date[0]; |
|
| 966 |
} |
|
| 967 |
else |
|
| 968 |
#endif |
|
| 969 |
if (want_era) |
|
| 970 |
return NULL; |
|
| 971 |
|
|
| 972 |
if (want_xday && !have_wday) |
|
| 973 |
{
|
|
| 974 |
if ( !(have_mon && have_mday) && have_yday) |
|
| 975 |
{
|
|
| 976 |
/* We don't have tm_mon and/or tm_mday, compute them. */ |
|
| 977 |
int t_mon = 0; |
|
| 978 |
while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) |
|
| 979 |
t_mon++; |
|
| 980 |
if (!have_mon) |
|
| 981 |
tm->tm_mon = t_mon - 1; |
|
| 982 |
if (!have_mday) |
|
| 983 |
tm->tm_mday = |
|
| 984 |
(tm->tm_yday |
|
| 985 |
- __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); |
|
| 986 |
} |
|
| 987 |
day_of_the_week (tm); |
|
| 988 |
} |
|
| 989 |
if (want_xday && !have_yday) |
|
| 990 |
day_of_the_year (tm); |
|
| 991 |
|
|
| 992 |
return (char *) rp; |
|
| 993 |
} |
|
| 994 |
|
|
| 995 |
|
|
| 996 |
char * |
|
| 997 |
strptime (const char *buf, const char *format, struct tm *tm) |
|
| 998 |
{
|
|
| 999 |
enum locale_status decided; |
|
| 1000 |
|
|
| 1001 |
#ifdef _NL_CURRENT |
|
| 1002 |
decided = not; |
|
| 1003 |
#else |
|
| 1004 |
decided = raw; |
|
| 1005 |
#endif |
|
| 1006 |
return strptime_internal (buf, format, tm, &decided, -1); |
|
| 1007 |
} |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/collection_alloc.h (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
#ifndef _COLLECTION_ALLOC_H_ |
|
| 20 |
#define _COLLECTION_ALLOC_H_ |
|
| 21 |
|
|
| 22 |
NNTPFile *file_new(void); |
|
| 23 |
void file_ref(NNTPFile *file); |
|
| 24 |
void file_unref(NNTPFile *file); |
|
| 25 |
NNTPCollection *collection_new(void); |
|
| 26 |
void collection_ref(NNTPCollection *collection); |
|
| 27 |
void collection_unref(NNTPCollection *collection); |
|
| 28 |
|
|
| 29 |
#endif /* _COLLECTION_ALLOC_H_ */ |
|
| tags/nntpgrab-0.6.91/nntpgrab_core/download_queue.c (revision 1801) | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
|
| 3 |
|
|
| 4 |
This program is free software; you can redistribute it and/or modify |
|
| 5 |
it under the terms of the GNU General Public License as published by |
|
| 6 |
the Free Software Foundation; either version 2 of the License, or |
|
| 7 |
(at your option) any later version. |
|
| 8 |
|
|
| 9 |
This program is distributed in the hope that it will be useful, |
|
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
GNU General Public License for more details. |
|
| 13 |
|
|
| 14 |
You should have received a copy of the GNU General Public License |
|
| 15 |
along with this program; if not, write to the Free Software |
|
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 17 |
*/ |
|
| 18 |
|
|
| 19 |
#include |
|
| 20 |
#include |
|
| 21 |
#include |
|
| 22 |
#include |
|
| 23 |
#include |
|
| 24 |
#include "nntpgrab.h" |
|
| 25 |
#include "nntpgrab_internal.h" |
|
| 26 |
#include "nntpgrab_plugin.h" |
|
| 27 |
#include "nntpgrab_utils.h" |
|
| 28 |
#include "nntpconnection.h" |
|
| 29 |
#include "queue_rawfile.h" |
|
| 30 |
#include "download_queue.h" |
|
| 31 |
#include "collection_alloc.h" |
|
| 32 |
#include "configuration.h" |
|
| 33 |
#include "decoder_thread.h" |
|
| 34 |
#include "download_thread.h" |
|
| 35 |
#include "plugins.h" |
|
| 36 |
|
|
| 37 |
static GStaticMutex mutex = G_STATIC_MUTEX_INIT; |
|
| 38 |
static GList *download_queue = NULL; |
|
| 39 |
static int num_servers = 0; |
|
| 40 |
static int num_enabled_servers = 0; |
|
| 41 |
static unsigned int is_high_priority_server; /* These are actually a bit-masked variable where every server has one bit */ |
|
| 42 |
static unsigned int is_normal_priority_server; |
|
| 43 |
static unsigned int is_server_enabled; |
|
| 44 |
static NGConfigOpts opts; |
|
| 45 |
|
|
| 46 |
static void |
|
| 47 |
rebuild_download_queue_list(NNTPCollection *collection) |
|
| 48 |
{
|
|
| 49 |
GList *list_file; |
|
| 50 |
|
|
| 51 |
// Clear out any old items in the list |
|
| 52 |
g_list_free(collection->files_to_download); |
|
| 53 |
collection->files_to_download = NULL; |
|
| 54 |
|
|
| 55 |
list_file = collection->files; |
|
| 56 |
while (list_file) {
|
|
| 57 |
NNTPFile *file = list_file->data; |
|
| 58 |
|
|
| 59 |
if (!file->file_is_downloaded) {
|
|
| 60 |
collection->files_to_download = g_list_append(collection->files_to_download, file); |
|
| 61 |
} |
|
| 62 |
|
|
| 63 |
list_file = g_list_next(list_file); |
|
Also available in: Unified diff
NNTPGrab

