Add memory debugging (--enable-mem-debug), find and fix several small (and not so small) memory leaks
This commit is contained in:
parent
b23f0d226b
commit
14fe9f9c6c
|
@ -6,13 +6,14 @@ AC_INIT(config.h.in)
|
|||
AM_CONFIG_HEADER(config.h)
|
||||
AM_INIT_AUTOMAKE(mt-daapd,0.2.1.1)
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
dnl AC_PROG_YACC
|
||||
dnl AM_PROG_LEX
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
AC_CHECK_HEADERS([sys/wait.h])
|
||||
AC_CHECK_HEADERS([sys/param.h])
|
||||
|
@ -115,6 +116,10 @@ AC_ARG_ENABLE(gdbm,[ --enable-gdbm Enable gdbm support],
|
|||
AC_ARG_ENABLE(ffmpeg,[ --enable-ffmpeg Enable ffmpeg transcode support],
|
||||
use_ffmpeg=true;)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(mem-debug,[ --enable-mem-debug Enable memory debugging],
|
||||
CPPFLAGS="${CPPFLAGS} -DDEBUG_MEM")
|
||||
|
||||
AM_CONDITIONAL(COND_REND_HOWL, test x$rend_howl = xtrue)
|
||||
AM_CONDITIONAL(COND_REND_POSIX, test x$rend_posix = xtrue)
|
||||
AM_CONDITIONAL(COND_REND_AVAHI, test x$rend_avahi = xtrue)
|
||||
|
|
|
@ -62,6 +62,7 @@ mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
|
|||
smart-parser.c smart-parser.h xml-rpc.c xml-rpc.h \
|
||||
os.h ll.c ll.h conf.c conf.h compat.c compat.h util.c util.h \
|
||||
os-unix.h os-unix.c os.h plugin.c plugin.h db-sql-updates.c \
|
||||
memdebug.c memdebug.h \
|
||||
$(PRENDSRC) $(ORENDSRC) $(HRENDSRC) $(ARENDSRC) $(OGGVORBISSRC) \
|
||||
$(FLACSRC) $(MUSEPACKSRC) $(SQLITEDB) $(SQLITE3DB) $(SQLDB) $(GDBM)
|
||||
|
||||
|
|
10
src/compat.c
10
src/compat.c
|
@ -8,6 +8,8 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "daapd.h"
|
||||
|
||||
#if !HAVE_STRCASESTR
|
||||
/* case-independent string matching, similar to strstr but
|
||||
* matching */
|
||||
|
@ -264,7 +266,7 @@ char *strptime(char *buf, char *fmt, struct tm *tm) {
|
|||
}
|
||||
|
||||
len = (int) strlen(En_US.pm_string);
|
||||
|
||||
|
||||
if (strncmp(buf, En_US.pm_string, len) == 0) {
|
||||
if (tm->tm_hour > 12)
|
||||
return 0;
|
||||
|
@ -373,7 +375,7 @@ char *strptime(char *buf, char *fmt, struct tm *tm) {
|
|||
i *= 10;
|
||||
i += *buf - '0';
|
||||
}
|
||||
|
||||
|
||||
if (c == 'Y')
|
||||
i -= 1900;
|
||||
else if (i < 69) /*c=='y', 00-68 is for 20xx, the rest is for 19xx*/
|
||||
|
@ -467,7 +469,7 @@ char *strtok_r(char *s, const char *delim, char **last)
|
|||
return NULL;
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
|
@ -504,7 +506,7 @@ time_t timegm(struct tm *tm) {
|
|||
_putenv("TZ=UTC0");
|
||||
_tzset();
|
||||
ret = mktime(tm);
|
||||
|
||||
|
||||
if(tz)
|
||||
sprintf(buffer,"TZ=%s",tz);
|
||||
else
|
||||
|
|
|
@ -48,10 +48,10 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "ll.h"
|
||||
#include "daapd.h"
|
||||
#include "os.h"
|
||||
#include "util.h"
|
||||
#include "webserver.h"
|
||||
|
@ -1696,5 +1696,6 @@ char *conf_get_servername(void) {
|
|||
retval[MAX_REND_LEN-3] = '.';
|
||||
}
|
||||
|
||||
free(template);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define os_syslog(a,b)
|
||||
#define os_closesyslog()
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "configfile.h"
|
||||
#include "db-generic.h"
|
||||
|
|
38
src/daapd.h
38
src/daapd.h
|
@ -31,7 +31,16 @@
|
|||
#ifndef _DAAPD_H_
|
||||
#define _DAAPD_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include "memdebug.h" /* redefine free/malloc/etc */
|
||||
#include "compat.h"
|
||||
#include "webserver.h"
|
||||
|
||||
|
@ -54,35 +63,6 @@ typedef struct tag_config {
|
|||
int foreground; /**< Whether or not we are running in foreground */
|
||||
int full_reload; /**< Whether the reload should be a full one */
|
||||
|
||||
#if 0
|
||||
char *configfile; /**< path to config file */
|
||||
char *web_root; /**< path to the dir containing the web files */
|
||||
char *iface; /**< interface to advertise on */
|
||||
int port; /**< port to listen on */
|
||||
int rescan_interval; /**< How often to do a background fs rescan */
|
||||
int always_scan; /**< 0 to minimize disk usage (embedded devices) */
|
||||
int process_m3u; /**< Should we process m3u files? */
|
||||
int scan_type; /**< Method for finding playtime. see scan-mp3.c */
|
||||
int compress; /**< Should we compress? */
|
||||
int latin1_tags; /**< interpret all tags as latin1 rather than utf8 */
|
||||
char *adminpassword; /**< Password to web management pages */
|
||||
char *readpassword; /**< iTunes password */
|
||||
char *mp3dir; /**< root directory of the mp3 files */
|
||||
char *servername; /**< Name advertised via rendezvous */
|
||||
char *playlist; /**< Path to the playlist file */
|
||||
char *runas; /**< Who to drop privs to (if run as root) */
|
||||
char *dbdir; /**< Where to put the db file */
|
||||
char *extensions; /**< What music file extentions to process */
|
||||
char *ssc_codectypes; /**< What codectypes are converted in server */
|
||||
char *ssc_prog; /**< Server side music format converter prog */
|
||||
char *artfilename; /**< What filename to merge coverart with */
|
||||
char *logfile; /**< What file to use as a logfile */
|
||||
char *compdirs; /**< Compilations directories */
|
||||
char *dbtype; /**< db backend type */
|
||||
char *dbparms; /**< parameters for the db backend */
|
||||
char **complist; /**< list of compilation directories */
|
||||
#endif
|
||||
|
||||
STATS stats; /**< Stats structure (see above) */
|
||||
WSHANDLE server; /**< webserver handle */
|
||||
} CONFIG;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "redblack.h"
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "db-generic.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
@ -62,7 +63,7 @@ typedef struct tag_db_functions {
|
|||
int(*dbs_edit_playlist)(char **, int, char*, char*);
|
||||
int(*dbs_playcount_increment)(char **, int);
|
||||
int(*dbs_enum_start)(char **, DBQUERYINFO *);
|
||||
int(*dbs_enum_fetch_row)(char **, PACKED_MP3FILE *, DBQUERYINFO *);
|
||||
int(*dbs_enum_fetch_row)(char **, PACKED_MP3FILE *, DBQUERYINFO *);
|
||||
int(*dbs_enum_reset)(char **, DBQUERYINFO *);
|
||||
int(*dbs_enum_end)(char **);
|
||||
int(*dbs_force_rescan)(char **);
|
||||
|
@ -466,7 +467,7 @@ int db_enum_start(char **pe, DBQUERYINFO *pinfo) {
|
|||
|
||||
/**
|
||||
* fetch the next item int he result set started by the db enum. this
|
||||
* will be in native packed row format
|
||||
* will be in native packed row format
|
||||
*/
|
||||
int db_enum_fetch_row(char **pe, PACKED_MP3FILE *row, DBQUERYINFO *pinfo) {
|
||||
return db_current->dbs_enum_fetch_row(pe, row, pinfo);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "db-generic.h"
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "db-generic.h"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "daapd.h"
|
||||
|
||||
char *db_sqlite_updates[] = {
|
||||
/* version 0 -> version 1 -- initial update */
|
||||
|
@ -47,7 +48,7 @@ char *db_sqlite_updates[] = {
|
|||
" sample_count INTEGER DEFAULT 0,\n"
|
||||
" force_update INTEGER DEFAULT 0\n"
|
||||
");\n"
|
||||
"CREATE INDEX idx_path ON songs(path);\n"
|
||||
"CREATE INDEX idx_path ON songs(path);\n"
|
||||
"CREATE TABLE config (\n"
|
||||
" term VARCHAR(255) NOT NULL,\n"
|
||||
" subterm VARCHAR(255) DEFAULT NULL,\n"
|
||||
|
@ -141,7 +142,7 @@ char *db_sqlite_updates[] = {
|
|||
"create index idx_path on songs(path);\n"
|
||||
"drop table tempsongs;\n"
|
||||
"update config set value=3 where term='version';\n",
|
||||
|
||||
|
||||
/* version 3 -> version 4 */
|
||||
/* add db_timestamp and path to playlist table */
|
||||
"create temp table tempplaylists as select * from playlists;\n"
|
||||
|
@ -240,13 +241,13 @@ char *db_sqlite_updates[] = {
|
|||
"insert into playlistitems (playlistid, songid) select * from tempitems;\n"
|
||||
"drop table tempitems;\n"
|
||||
"update config set value=7 where term='version';\n",
|
||||
|
||||
|
||||
/* version 7 -> version 8 */
|
||||
"create index idx_songid on playlistitems(songid)\n"
|
||||
"create index idx_playlistid on playlistitems(playlistid)\n"
|
||||
"update config set value=8 where term='version';\n",
|
||||
|
||||
/* version 8 -> version 9 */
|
||||
/* version 8 -> version 9 */
|
||||
"drop index idx_path;\n"
|
||||
"create temp table tempsongs as select * from songs;\n"
|
||||
"drop table songs;\n"
|
||||
|
@ -301,7 +302,7 @@ char *db_sqlite_updates[] = {
|
|||
"drop table tempsongs;\n"
|
||||
"update config set value=9 where term='version';\n",
|
||||
|
||||
/* version 9 -> version 10 */
|
||||
/* version 9 -> version 10 */
|
||||
"drop index idx_path;\n"
|
||||
"create temp table tempsongs as select * from songs;\n"
|
||||
"drop table songs;\n"
|
||||
|
@ -354,7 +355,7 @@ char *db_sqlite_updates[] = {
|
|||
"create index idx_path on songs(path,idx);\n"
|
||||
"drop table tempsongs;\n"
|
||||
"update config set value=10 where term='version';\n",
|
||||
/* version 10 -> version 11 */
|
||||
/* version 10 -> version 11 */
|
||||
"drop index idx_playlistid;\n"
|
||||
"create index idx_playlistid on playlistitems(playlistid,songid);\n"
|
||||
"update config set value=11 where term='version';\n",
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "db-generic.h"
|
||||
|
@ -1624,6 +1625,7 @@ void db_sql_dispose_item(MP3FILE *pmp3) {
|
|||
MAYBEFREE(pmp3->description);
|
||||
MAYBEFREE(pmp3->url);
|
||||
MAYBEFREE(pmp3->codectype);
|
||||
MAYBEFREE(pmp3->album_artist);
|
||||
free(pmp3);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "configfile.h"
|
||||
#include "err.h"
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#ifndef ERR_LEAN
|
||||
# include "os.h"
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "daapd.h"
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
|
|
7
src/ll.c
7
src/ll.c
|
@ -28,6 +28,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "ll.h"
|
||||
#include "err.h"
|
||||
|
||||
|
@ -126,11 +127,11 @@ int ll_del_item(LL *pl, char *key) {
|
|||
phead = pl->itemlist.next;
|
||||
|
||||
while(phead) {
|
||||
if((pl->flags & LL_FLAG_HONORCASE) &&
|
||||
if((pl->flags & LL_FLAG_HONORCASE) &&
|
||||
(strcmp(phead->key,key)==0))
|
||||
break;
|
||||
if((!(pl->flags & LL_FLAG_HONORCASE) &&
|
||||
(strcasecmp(phead->key,key)==0)))
|
||||
if((!(pl->flags & LL_FLAG_HONORCASE) &&
|
||||
(strcasecmp(phead->key,key)==0)))
|
||||
break;
|
||||
|
||||
ptail=phead;
|
||||
|
|
268
src/mDNS.c
268
src/mDNS.c
|
@ -2,14 +2,14 @@
|
|||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
|
@ -17,12 +17,12 @@
|
|||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
* This code is completely 100% portable C. It does not depend on any external header files
|
||||
* from outside the mDNS project -- all the types it expects to find are defined right here.
|
||||
*
|
||||
*
|
||||
* The previous point is very important: This file does not depend on any external
|
||||
* header files. It should complile on *any* platform that has a C compiler, without
|
||||
* making *any* assumptions about availability of so-called "standard" C functions,
|
||||
|
@ -1016,19 +1016,19 @@ Merge in license terms from Quinn's copy, in preparation for Darwin release
|
|||
|
||||
#include "mDNSClientAPI.h" // Defines the interface provided to the client layer above
|
||||
#include "mDNSPlatformFunctions.h" // Defines the interface required of the supporting layer below
|
||||
|
||||
#include "daapd.h"
|
||||
// Disable certain benign warnings with Microsoft compilers
|
||||
#if(defined(_MSC_VER))
|
||||
// Disable "conditional expression is constant" warning for debug macros.
|
||||
// Otherwise, this generates warnings for the perfectly natural construct "while(1)"
|
||||
// If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
|
||||
#pragma warning(disable:4127)
|
||||
|
||||
|
||||
// Disable "const object should be initialized"
|
||||
// We know that static/globals are defined to be zeroed in ANSI C, and to avoid this warning would require some
|
||||
// *really* ugly chunk of zeroes and curly braces to initialize zeroRR and mDNSprintf_format_default to all zeroes
|
||||
#pragma warning(disable:4132)
|
||||
|
||||
|
||||
// Disable "assignment within conditional expression".
|
||||
// Other compilers understand the convention that if you place the assignment expression within an extra pair
|
||||
// of parentheses, this signals to the compiler that you really intended an assignment and no warning is necessary.
|
||||
|
@ -1047,7 +1047,7 @@ typedef enum
|
|||
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
||||
kDNSFlag0_QR_Query = 0x00,
|
||||
kDNSFlag0_QR_Response = 0x80,
|
||||
|
||||
|
||||
kDNSFlag0_OP_Mask = 0x78, // Operation type
|
||||
kDNSFlag0_OP_StdQuery = 0x00,
|
||||
kDNSFlag0_OP_Iquery = 0x08,
|
||||
|
@ -1055,14 +1055,14 @@ typedef enum
|
|||
kDNSFlag0_OP_Unused3 = 0x18,
|
||||
kDNSFlag0_OP_Notify = 0x20,
|
||||
kDNSFlag0_OP_Update = 0x28,
|
||||
|
||||
|
||||
kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
|
||||
|
||||
|
||||
kDNSFlag0_AA = 0x04, // Authoritative Answer?
|
||||
kDNSFlag0_TC = 0x02, // Truncated?
|
||||
kDNSFlag0_RD = 0x01, // Recursion Desired?
|
||||
kDNSFlag1_RA = 0x80, // Recursion Available?
|
||||
|
||||
|
||||
kDNSFlag1_Zero = 0x40, // Reserved; must be zero
|
||||
kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
|
||||
kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
|
||||
|
@ -1176,7 +1176,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
#define mDNS_VACB_Remain(s) ((mDNSu32)(mDNS_VACB_Lim - s))
|
||||
char *s = mDNS_VACB_Lim, *digits;
|
||||
struct mDNSprintf_format F = mDNSprintf_format_default;
|
||||
|
||||
|
||||
while (1) // decode flags
|
||||
{
|
||||
c = *++fmt;
|
||||
|
@ -1187,7 +1187,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
else if (c == '0') F.zeroPad = 1;
|
||||
else break;
|
||||
}
|
||||
|
||||
|
||||
if (c == '*') // decode field width
|
||||
{
|
||||
int f = va_arg(arg, int);
|
||||
|
@ -1200,7 +1200,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
for (; c >= '0' && c <= '9'; c = *++fmt)
|
||||
F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
|
||||
}
|
||||
|
||||
|
||||
if (c == '.') // decode precision
|
||||
{
|
||||
if ((c = *++fmt) == '*')
|
||||
|
@ -1209,9 +1209,9 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
F.precision = (10 * F.precision) + (c - '0');
|
||||
F.havePrecision = 1;
|
||||
}
|
||||
|
||||
|
||||
if (F.leftJustify) F.zeroPad = 0;
|
||||
|
||||
|
||||
conv:
|
||||
switch (c) // perform appropriate conversion
|
||||
{
|
||||
|
@ -1246,7 +1246,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
for (; i < F.precision; i++) *--s = '0';
|
||||
if (F.sign) { *--s = F.sign; i++; }
|
||||
break;
|
||||
|
||||
|
||||
case 'o' : if (F.lSize) n = va_arg(arg, unsigned long);
|
||||
else n = va_arg(arg, unsigned int);
|
||||
if (F.hSize) n = (unsigned short) n;
|
||||
|
@ -1261,7 +1261,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
if (F.altForm && i && *s != '0') { *--s = '0'; i++; }
|
||||
for (; i < F.precision; i++) *--s = '0';
|
||||
break;
|
||||
|
||||
|
||||
case 'a' : {
|
||||
unsigned char *a = va_arg(arg, unsigned char *);
|
||||
if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
|
||||
|
@ -1295,7 +1295,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'p' : F.havePrecision = F.lSize = 1;
|
||||
F.precision = 8;
|
||||
case 'X' : digits = "0123456789ABCDEF";
|
||||
|
@ -1319,9 +1319,9 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
for (; i < F.precision; i++) *--s = '0';
|
||||
if (F.altForm) { *--s = (char)c; *--s = '0'; i += 2; }
|
||||
break;
|
||||
|
||||
|
||||
case 'c' : *--s = (char)va_arg(arg, int); i = 1; break;
|
||||
|
||||
|
||||
case 's' : s = va_arg(arg, char *);
|
||||
if (!s) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
|
||||
else switch (F.altForm)
|
||||
|
@ -1347,13 +1347,13 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
if (F.havePrecision && i > F.precision) // Make sure we don't truncate in the middle of a UTF-8 character
|
||||
{ i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--; }
|
||||
break;
|
||||
|
||||
|
||||
case 'n' : s = va_arg(arg, char *);
|
||||
if (F.hSize) * (short *) s = (short)nwritten;
|
||||
else if (F.lSize) * (long *) s = (long)nwritten;
|
||||
else * (int *) s = (int)nwritten;
|
||||
continue;
|
||||
|
||||
|
||||
default: s = mDNS_VACB;
|
||||
i = mDNS_snprintf(mDNS_VACB, sizeof(mDNS_VACB), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c);
|
||||
|
||||
|
@ -1361,19 +1361,19 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
if (++nwritten >= buflen) goto exit;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (i < F.fieldWidth && !F.leftJustify) // Pad on the left
|
||||
do {
|
||||
*sbuffer++ = ' ';
|
||||
if (++nwritten >= buflen) goto exit;
|
||||
} while (i < --F.fieldWidth);
|
||||
|
||||
|
||||
if (i > buflen - nwritten) // Make sure we don't truncate in the middle of a UTF-8 character
|
||||
{ i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--; }
|
||||
for (j=0; j<i; j++) *sbuffer++ = *s++; // Write the converted result
|
||||
nwritten += i;
|
||||
if (nwritten >= buflen) goto exit;
|
||||
|
||||
|
||||
for (; i < F.fieldWidth; i++) // Pad on the right
|
||||
{
|
||||
*sbuffer++ = ' ';
|
||||
|
@ -1389,12 +1389,12 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
mDNSexport mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...)
|
||||
{
|
||||
mDNSu32 length;
|
||||
|
||||
|
||||
va_list ptr;
|
||||
va_start(ptr,fmt);
|
||||
length = mDNS_vsnprintf(sbuffer, buflen, fmt, ptr);
|
||||
va_end(ptr);
|
||||
|
||||
|
||||
return(length);
|
||||
}
|
||||
|
||||
|
@ -1449,7 +1449,7 @@ mDNSlocal mDNSu32 mDNSRandom(mDNSu32 max)
|
|||
{
|
||||
static mDNSu32 seed = 0;
|
||||
mDNSu32 mask = 1;
|
||||
|
||||
|
||||
if (!seed) seed = (mDNSu32)mDNSPlatformTimeNow();
|
||||
while (mask < max) mask = (mask << 1) | 1;
|
||||
do seed = seed * 21 + 1; while ((seed & mask) > max);
|
||||
|
@ -1571,7 +1571,7 @@ mDNSexport mDNSBool SameDomainName(const domainname *const d1, const domainname
|
|||
a += 1 + *a;
|
||||
b += 1 + *b;
|
||||
}
|
||||
|
||||
|
||||
return(mDNStrue);
|
||||
}
|
||||
|
||||
|
@ -1629,7 +1629,7 @@ mDNSexport mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *
|
|||
const mDNSu8 *const lim2 = ptr + 1 + MAX_DOMAIN_LABEL;
|
||||
const mDNSu8 *const lim = (lim1 < lim2) ? lim1 : lim2;
|
||||
mDNSu8 *lengthbyte = ptr++; // Record where the length is going to go
|
||||
|
||||
|
||||
while (*cstr && ptr < lim) *ptr++ = (mDNSu8)*cstr++; // Copy the data
|
||||
*lengthbyte = (mDNSu8)(ptr - lengthbyte - 1); // Fill in the length byte
|
||||
*ptr++ = 0; // Put the null root label on the end
|
||||
|
@ -1782,7 +1782,7 @@ mDNSexport char *ConvertDomainNameToCString_withescape(const domainname *const n
|
|||
{
|
||||
const mDNSu8 *src = name->c; // Domain name we're reading
|
||||
const mDNSu8 *const max = name->c + MAX_DOMAIN_NAME; // Maximum that's valid
|
||||
|
||||
|
||||
if (*src == 0) *ptr++ = '.'; // Special case: For root, just write a dot
|
||||
|
||||
while (*src) // While more characters in the domain name
|
||||
|
@ -1858,7 +1858,7 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
|
|||
}
|
||||
else
|
||||
name = (domainlabel*)""; // Set this up to be non-null, to avoid errors if we have to call LogMsg() below
|
||||
|
||||
|
||||
src = type->c; // Put the service type into the domain name
|
||||
len = *src;
|
||||
if (len < 2 || len >= 0x40) { errormsg="Invalid service application protocol name"; goto fail; }
|
||||
|
@ -1875,9 +1875,9 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
|
|||
(src[4] | 0x20) == 'p'))
|
||||
{ errormsg="Service transport protocol name must be _udp or _tcp"; goto fail; }
|
||||
for (i=0; i<=len; i++) *dst++ = *src++;
|
||||
|
||||
|
||||
if (*src) { errormsg="Service type must have only two labels"; goto fail; }
|
||||
|
||||
|
||||
*dst = 0;
|
||||
dst = AppendDomainName(fqdn, domain);
|
||||
if (!dst) { errormsg="Service domain too long"; goto fail; }
|
||||
|
@ -1895,12 +1895,12 @@ mDNSexport mDNSBool DeconstructServiceName(const domainname *const fqdn,
|
|||
const mDNSu8 *src = fqdn->c;
|
||||
const mDNSu8 *max = fqdn->c + MAX_DOMAIN_NAME;
|
||||
mDNSu8 *dst;
|
||||
|
||||
|
||||
dst = name->c; // Extract the service name from the domain name
|
||||
len = *src;
|
||||
if (len >= 0x40) { debugf("DeconstructServiceName: service name too long"); return(mDNSfalse); }
|
||||
for (i=0; i<=len; i++) *dst++ = *src++;
|
||||
|
||||
|
||||
dst = type->c; // Extract the service type from the domain name
|
||||
len = *src;
|
||||
if (len >= 0x40) { debugf("DeconstructServiceName: service type too long"); return(mDNSfalse); }
|
||||
|
@ -1922,7 +1922,7 @@ mDNSexport mDNSBool DeconstructServiceName(const domainname *const fqdn,
|
|||
for (i=0; i<=len; i++) *dst++ = *src++;
|
||||
}
|
||||
*dst++ = 0; // Put the null root label on the end
|
||||
|
||||
|
||||
return(mDNStrue);
|
||||
}
|
||||
|
||||
|
@ -1931,7 +1931,7 @@ mDNSexport mDNSBool DeconstructServiceName(const domainname *const fqdn,
|
|||
mDNSlocal mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText)
|
||||
{
|
||||
mDNSu16 l = name->c[0];
|
||||
|
||||
|
||||
if (RichText)
|
||||
{
|
||||
if (l < 4) return mDNSfalse; // Need at least " (2)"
|
||||
|
@ -1984,7 +1984,7 @@ mDNSlocal void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichTe
|
|||
{
|
||||
mDNSu32 divisor = 1, chars = 2; // Shortest possible RFC1034 name suffix is 3 characters ("-2")
|
||||
if (RichText) chars = 4; // Shortest possible RichText suffix is 4 characters (" (2)")
|
||||
|
||||
|
||||
// Truncate trailing spaces from RichText names
|
||||
if (RichText) while (name->c[name->c[0]] == ' ') name->c[0]--;
|
||||
|
||||
|
@ -2000,7 +2000,7 @@ mDNSlocal void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichTe
|
|||
|
||||
if (RichText) { name->c[++name->c[0]] = ' '; name->c[++name->c[0]] = '('; }
|
||||
else { name->c[++name->c[0]] = '-'; }
|
||||
|
||||
|
||||
while (divisor)
|
||||
{
|
||||
name->c[++name->c[0]] = (mDNSu8)('0' + val / divisor);
|
||||
|
@ -2017,7 +2017,7 @@ mDNSexport void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText)
|
|||
|
||||
if (LabelContainsSuffix(name, RichText))
|
||||
val = RemoveLabelSuffix(name, RichText);
|
||||
|
||||
|
||||
// If no existing suffix, start by renaming "Foo" as "Foo (2)" or "Foo-2" as appropriate.
|
||||
// If existing suffix in the range 2-9, increment it.
|
||||
// If we've had ten conflicts already, there are probably too many hosts trying to use the same name,
|
||||
|
@ -2025,7 +2025,7 @@ mDNSexport void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText)
|
|||
if (val == 0) val = 2;
|
||||
else if (val < 10) val++;
|
||||
else val += 1 + mDNSRandom(99);
|
||||
|
||||
|
||||
AppendLabelSuffix(name, val, RichText);
|
||||
}
|
||||
|
||||
|
@ -2197,7 +2197,7 @@ mDNSlocal mDNSBool ShouldSuppressKnownAnswer(const CacheRecord *const ka, const
|
|||
{
|
||||
// If RR signature is different, or data is different, then don't suppress our answer
|
||||
if (!IdenticalResourceRecord(&ka->resrec,&rr->resrec)) return(mDNSfalse);
|
||||
|
||||
|
||||
// If the requester's indicated TTL is less than half the real TTL,
|
||||
// we need to give our answer before the requester's copy expires.
|
||||
// If the requester's indicated TTL is at least half the real TTL,
|
||||
|
@ -2267,7 +2267,7 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
|
|||
if (m->SuppressProbes - m->NextScheduledQuery >= 0)
|
||||
m->SuppressProbes = m->NextScheduledQuery;
|
||||
}
|
||||
|
||||
|
||||
// We announce to flush stale data from other caches. It is a reasonable assumption that any
|
||||
// old stale copies will probably have the same TTL we're using, so announcing longer than
|
||||
// this serves no purpose -- any stale copies of that record will have expired by then anyway.
|
||||
|
@ -2277,7 +2277,7 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
|
|||
// (no need to send additional multicast responses when we're announcing anyway)
|
||||
rr->LastMCTime = m->timenow;
|
||||
rr->LastMCInterface = mDNSInterfaceMark;
|
||||
|
||||
|
||||
// If this is a record type that's not going to probe, then delay its first announcement so that
|
||||
// it will go out synchronized with the first announcement for the other records that *are* probing.
|
||||
// This is a minor performance tweak that helps keep groups of related records synchronized together.
|
||||
|
@ -2287,7 +2287,7 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
|
|||
// because they will meet the criterion of being at least half-way to their scheduled announcement time.
|
||||
if (rr->resrec.RecordType != kDNSRecordTypeUnique)
|
||||
rr->LastAPTime += DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
|
||||
|
||||
|
||||
SetNextAnnounceProbeTime(m, rr);
|
||||
}
|
||||
|
||||
|
@ -2315,12 +2315,12 @@ mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
|
|||
|
||||
if (target && SameDomainName(target, &m->hostname))
|
||||
debugf("SetTargetToHostName: Target of %##s is already %##s", rr->resrec.name.c, target->c);
|
||||
|
||||
|
||||
if (target && !SameDomainName(target, &m->hostname))
|
||||
{
|
||||
AssignDomainName(*target, m->hostname);
|
||||
SetNewRData(&rr->resrec, mDNSNULL, 0);
|
||||
|
||||
|
||||
// If we're in the middle of probing this record, we need to start again,
|
||||
// because changing its rdata may change the outcome of the tie-breaker.
|
||||
// (If the record type is kDNSRecordTypeUnique (unconfirmed unique) then DefaultProbeCountForRecordType is non-zero.)
|
||||
|
@ -2407,7 +2407,7 @@ mDNSlocal mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
|
|||
AuthRecord **p = &m->ResourceRecords;
|
||||
AuthRecord **d = &m->DuplicateRecords;
|
||||
AuthRecord **l = &m->LocalOnlyRecords;
|
||||
|
||||
|
||||
#if TEST_LOCALONLY_FOR_EVERYTHING
|
||||
rr->resrec.InterfaceID = (mDNSInterfaceID)~0;
|
||||
#endif
|
||||
|
@ -2518,7 +2518,7 @@ mDNSlocal mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
|
|||
rr->resrec.namehash = DomainNameHashValue(&rr->resrec.name);
|
||||
rr->resrec.rdatahash = RDataHashValue(rr->resrec.rdlength, &rr->resrec.rdata->u);
|
||||
rr->resrec.rdnamehash = target ? DomainNameHashValue(target) : 0;
|
||||
|
||||
|
||||
if (rr->resrec.InterfaceID == ((mDNSInterfaceID)~0))
|
||||
{
|
||||
debugf("Adding %p %##s (%s) to LocalOnly list", rr, rr->resrec.name.c, DNSTypeName(rr->resrec.rrtype));
|
||||
|
@ -2550,7 +2550,7 @@ mDNSlocal mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
|
|||
{
|
||||
// Now that's we've finished building our new record, make sure it's not identical to one we already have
|
||||
for (r = m->ResourceRecords; r; r=r->next) if (RecordIsLocalDuplicate(r, rr)) break;
|
||||
|
||||
|
||||
if (r)
|
||||
{
|
||||
debugf("Adding %p %##s (%s) to duplicate list", rr, rr->resrec.name.c, DNSTypeName(rr->resrec.rrtype));
|
||||
|
@ -2705,7 +2705,7 @@ mDNSlocal mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr,
|
|||
if (rr->UpdateCallback)
|
||||
rr->UpdateCallback(m, rr, OldRData); // ... and let the client know
|
||||
}
|
||||
|
||||
|
||||
// CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
|
||||
// is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
|
||||
// In this case the likely client action to the mStatus_MemFree message is to free the memory,
|
||||
|
@ -2749,7 +2749,7 @@ mDNSlocal const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const m
|
|||
const mDNSu8 *result = end - *domname - 1;
|
||||
|
||||
if (*domname == 0) return(mDNSNULL); // There's no point trying to match just the root label
|
||||
|
||||
|
||||
// This loop examines each possible starting position in packet, starting end of the packet and working backwards
|
||||
while (result >= base)
|
||||
{
|
||||
|
@ -2806,7 +2806,7 @@ mDNSlocal mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg,
|
|||
{
|
||||
if (*np > MAX_DOMAIN_LABEL)
|
||||
{ LogMsg("Malformed domain name %##s (label more than 63 bytes)", name->c); return(mDNSNULL); }
|
||||
|
||||
|
||||
// This check correctly allows for the final trailing root label:
|
||||
// e.g.
|
||||
// Suppose our domain name is exactly 255 bytes long, including the final trailing root label.
|
||||
|
@ -2900,7 +2900,7 @@ mDNSlocal mDNSu8 *PutResourceRecordTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu
|
|||
mDNSu8 *endofrdata;
|
||||
mDNSu16 actualLength;
|
||||
const mDNSu8 *limit = msg->data + AbsoluteMaxDNSMessageData;
|
||||
|
||||
|
||||
// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
|
||||
// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
|
||||
if (msg->h.numAnswers || msg->h.numAuthorities || msg->h.numAdditionals)
|
||||
|
@ -3053,7 +3053,7 @@ mDNSlocal const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nextbyte) return(nextbyte);
|
||||
else return(ptr);
|
||||
}
|
||||
|
@ -3064,7 +3064,7 @@ mDNSlocal const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *
|
|||
|
||||
ptr = skipDomainName(msg, ptr, end);
|
||||
if (!ptr) { debugf("skipResourceRecord: Malformed RR name"); return(mDNSNULL); }
|
||||
|
||||
|
||||
if (ptr + 10 > end) { debugf("skipResourceRecord: Malformed RR -- no type/class/ttl/len!"); return(mDNSNULL); }
|
||||
pktrdlength = (mDNSu16)((mDNSu16)ptr[8] << 8 | ptr[9]);
|
||||
ptr += 10;
|
||||
|
@ -3103,7 +3103,7 @@ mDNSlocal const mDNSu8 *GetResourceRecord(mDNS *const m, const DNSMessage *msg,
|
|||
if (!ptr) { debugf("GetResourceRecord: Malformed RR name"); return(mDNSNULL); }
|
||||
|
||||
if (ptr + 10 > end) { debugf("GetResourceRecord: Malformed RR -- no type/class/ttl/len!"); return(mDNSNULL); }
|
||||
|
||||
|
||||
rr->resrec.rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
|
||||
rr->resrec.rrclass = (mDNSu16)(((mDNSu16)ptr[2] << 8 | ptr[3]) & kDNSClass_Mask);
|
||||
rr->resrec.rroriginalttl = (mDNSu32) ((mDNSu32)ptr[4] << 24 | (mDNSu32)ptr[5] << 16 | (mDNSu32)ptr[6] << 8 | ptr[7]);
|
||||
|
@ -3240,7 +3240,7 @@ mDNSlocal mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg,
|
|||
mDNSu16 numAnswers = msg->h.numAnswers;
|
||||
mDNSu16 numAuthorities = msg->h.numAuthorities;
|
||||
mDNSu16 numAdditionals = msg->h.numAdditionals;
|
||||
|
||||
|
||||
// Put all the integer values in IETF byte-order (MSB first, LSB second)
|
||||
mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
|
||||
*ptr++ = (mDNSu8)(numQuestions >> 8);
|
||||
|
@ -3251,10 +3251,10 @@ mDNSlocal mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg,
|
|||
*ptr++ = (mDNSu8)(numAuthorities );
|
||||
*ptr++ = (mDNSu8)(numAdditionals >> 8);
|
||||
*ptr++ = (mDNSu8)(numAdditionals );
|
||||
|
||||
|
||||
// Send the packet on the wire
|
||||
status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, srcport, dst, dstport);
|
||||
|
||||
|
||||
// Put all the integer values back the way they were before we return
|
||||
msg->h.numQuestions = numQuestions;
|
||||
msg->h.numAnswers = numAnswers;
|
||||
|
@ -3280,7 +3280,7 @@ mDNSlocal void DiscardDeregistrations(mDNS *const m)
|
|||
{
|
||||
if (m->CurrentRecord) LogMsg("DiscardDeregistrations ERROR m->CurrentRecord already set");
|
||||
m->CurrentRecord = m->ResourceRecords;
|
||||
|
||||
|
||||
while (m->CurrentRecord)
|
||||
{
|
||||
AuthRecord *rr = m->CurrentRecord;
|
||||
|
@ -3333,7 +3333,7 @@ mDNSlocal void SendResponses(mDNS *const m)
|
|||
{
|
||||
if (rr->NextUpdateCredit && m->timenow - rr->NextUpdateCredit >= 0)
|
||||
{
|
||||
if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
|
||||
if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
|
||||
else rr->NextUpdateCredit = (m->timenow + mDNSPlatformOneSecond * 60) | 1;
|
||||
}
|
||||
if (TimeToAnnounceThisRecord(rr, m->timenow) && ResourceRecordIsValidAnswer(rr))
|
||||
|
@ -3433,7 +3433,7 @@ mDNSlocal void SendResponses(mDNS *const m)
|
|||
mDNSu8 *responseptr = response.data;
|
||||
mDNSu8 *newptr;
|
||||
InitializeDNSMessage(&response.h, zeroID, ResponseFlags);
|
||||
|
||||
|
||||
// First Pass. Look for:
|
||||
// 1. Deregistering records that need to send their goodbye packet
|
||||
// 2. Updated records that need to retract their old data
|
||||
|
@ -3491,7 +3491,7 @@ mDNSlocal void SendResponses(mDNS *const m)
|
|||
else
|
||||
rr->SendRNow = mDNSNULL;
|
||||
}
|
||||
|
||||
|
||||
// Second Pass. Add additional records, if there's space.
|
||||
newptr = responseptr;
|
||||
for (rr = m->ResourceRecords; rr; rr=rr->next)
|
||||
|
@ -3515,7 +3515,7 @@ mDNSlocal void SendResponses(mDNS *const m)
|
|||
rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet; // Make sure to clear cache flush bit back to normal state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (response.h.numAnswers > 0) // We *never* send a packet with only additionals in it
|
||||
{
|
||||
debugf("SendResponses: Sending %d Deregistration%s, %d Announcement%s, %d Answer%s, %d Additional%s on %p",
|
||||
|
@ -3782,12 +3782,12 @@ mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDN
|
|||
if (!ds[j].InterfaceID || ds[j].Time - ds[i].Time < 0)
|
||||
i = j;
|
||||
}
|
||||
|
||||
|
||||
// Record the info about this query we saw
|
||||
ds[i].Time = Time;
|
||||
ds[i].InterfaceID = InterfaceID;
|
||||
ds[i].Type = Type;
|
||||
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
|
@ -3868,7 +3868,7 @@ mDNSlocal void SendQueries(mDNS *const m)
|
|||
if (maxExistingQuestionInterval < q->ThisQInterval)
|
||||
maxExistingQuestionInterval = q->ThisQInterval;
|
||||
}
|
||||
|
||||
|
||||
// Scan our list of questions
|
||||
// (a) to see if there are any more that are worth accelerating, and
|
||||
// (b) to update the state variables for all the questions we're going to send
|
||||
|
@ -3977,7 +3977,7 @@ mDNSlocal void SendQueries(mDNS *const m)
|
|||
// Start a new known-answer list
|
||||
CacheRecord **kalistptr = &KnownAnswerList;
|
||||
mDNSu32 answerforecast = 0;
|
||||
|
||||
|
||||
// Put query questions in this packet
|
||||
for (q = m->Questions; q; q=q->next)
|
||||
if (q->SendQNow == intf->InterfaceID)
|
||||
|
@ -4050,7 +4050,7 @@ mDNSlocal void SendQueries(mDNS *const m)
|
|||
else LogMsg("SendQueries: How did we fail to have space for the Update record %##s (%s)?",
|
||||
rr->resrec.name.c, DNSTypeName(rr->resrec.rrtype));
|
||||
}
|
||||
|
||||
|
||||
if (queryptr > query.data)
|
||||
{
|
||||
if ((query.h.flags.b[0] & kDNSFlag0_TC) && query.h.numQuestions > 1)
|
||||
|
@ -4389,14 +4389,14 @@ mDNSlocal CacheRecord *GetFreeCacheRR(mDNS *const m, mDNSu16 RDLength)
|
|||
|
||||
if (m->lock_rrcache) { LogMsg("GetFreeCacheRR ERROR! Cache already locked!"); return(mDNSNULL); }
|
||||
m->lock_rrcache = 1;
|
||||
|
||||
|
||||
// If we have no free records, ask the client layer to give us some more memory
|
||||
if (!m->rrcache_free && m->MainCallback)
|
||||
{
|
||||
if (m->rrcache_totalused != m->rrcache_size)
|
||||
LogMsg("GetFreeCacheRR: count mismatch: m->rrcache_totalused %lu != m->rrcache_size %lu",
|
||||
m->rrcache_totalused, m->rrcache_size);
|
||||
|
||||
|
||||
// We don't want to be vulnerable to a malicious attacker flooding us with an infinite
|
||||
// number of bogus records so that we keep growing our cache until the machine runs out of memory.
|
||||
// To guard against this, if we're actively using less than 1/32 of our cache, then we
|
||||
|
@ -4407,7 +4407,7 @@ mDNSlocal CacheRecord *GetFreeCacheRR(mDNS *const m, mDNSu16 RDLength)
|
|||
else
|
||||
m->MainCallback(m, mStatus_GrowCache);
|
||||
}
|
||||
|
||||
|
||||
// If we still have no free records, recycle all the records we can.
|
||||
// Enumerating the entire cache is moderately expensive, so when we do it, we reclaim all the records we can in one pass.
|
||||
if (!m->rrcache_free)
|
||||
|
@ -4439,7 +4439,7 @@ mDNSlocal CacheRecord *GetFreeCacheRR(mDNS *const m, mDNSu16 RDLength)
|
|||
debugf("Clear unused records; m->rrcache_totalused was %lu; now %lu", oldtotalused, m->rrcache_totalused);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (m->rrcache_free) // If there are records in the free list, take one
|
||||
{
|
||||
r = m->rrcache_free;
|
||||
|
@ -4456,7 +4456,7 @@ mDNSlocal CacheRecord *GetFreeCacheRR(mDNS *const m, mDNSu16 RDLength)
|
|||
}
|
||||
mDNSPlatformMemZero(r, sizeof(*r));
|
||||
r->resrec.rdata = (RData*)&r->rdatastorage; // By default, assume we're usually going to be using local storage
|
||||
|
||||
|
||||
if (RDLength > InlineCacheRDSize) // If RDLength is too big, allocate extra storage
|
||||
{
|
||||
r->resrec.rdata = (RData*)mDNSPlatformMemAllocate(sizeofRDataHeader + RDLength);
|
||||
|
@ -4543,7 +4543,7 @@ mDNSlocal void mDNS_Unlock(mDNS *const m)
|
|||
{
|
||||
// Decrement mDNS_busy
|
||||
m->mDNS_busy--;
|
||||
|
||||
|
||||
// Check for locking failures
|
||||
if (m->mDNS_busy != m->mDNS_reentrancy)
|
||||
LogMsg("mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
|
||||
|
@ -4570,13 +4570,13 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
|
|||
|
||||
verbosedebugf("mDNS_Execute");
|
||||
if (m->CurrentQuestion) LogMsg("mDNS_Execute: ERROR! m->CurrentQuestion already set");
|
||||
|
||||
|
||||
// 1. If we're past the probe suppression time, we can clear it
|
||||
if (m->SuppressProbes && m->timenow - m->SuppressProbes >= 0) m->SuppressProbes = 0;
|
||||
|
||||
|
||||
// 2. If it's been more than ten seconds since the last probe failure, we can clear the counter
|
||||
if (m->NumFailedProbes && m->timenow - m->ProbeFailTime >= mDNSPlatformOneSecond * 10) m->NumFailedProbes = 0;
|
||||
|
||||
|
||||
// 3. Purge our cache of stale old records
|
||||
if (m->rrcache_size && m->timenow - m->NextCacheCheck >= 0)
|
||||
{
|
||||
|
@ -4584,11 +4584,11 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
|
|||
m->NextCacheCheck = m->timenow + 0x3FFFFFFF;
|
||||
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++) CheckCacheExpiration(m, slot);
|
||||
}
|
||||
|
||||
|
||||
// 4. See if we can answer any of our new local questions from the cache
|
||||
for (i=0; m->NewQuestions && i<1000; i++) AnswerNewQuestion(m);
|
||||
if (i >= 1000) debugf("mDNS_Execute: AnswerNewQuestion exceeded loop limit");
|
||||
|
||||
|
||||
for (i=0; m->DiscardLocalOnlyRecords && i<1000; i++) DiscardLocalOnlyRecords(m);
|
||||
if (i >= 1000) debugf("mDNS_Execute: DiscardLocalOnlyRecords exceeded loop limit");
|
||||
|
||||
|
@ -4609,7 +4609,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
|
|||
// them to advance to announcing state, and we want those to be included in any announcements we send out.
|
||||
// Finally, we send responses, including the previously mentioned records that just completed probing
|
||||
m->SuppressSending = 0;
|
||||
|
||||
|
||||
// 6. Send Query packets. This may cause some probing records to advance to announcing state
|
||||
if (m->timenow - m->NextScheduledQuery >= 0 || m->timenow - m->NextScheduledProbe >= 0) SendQueries(m);
|
||||
if (m->timenow - m->NextScheduledQuery >= 0)
|
||||
|
@ -4622,7 +4622,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
|
|||
LogMsg("mDNS_Execute: SendQueries didn't send all its probes; will try again in one second");
|
||||
m->NextScheduledProbe = m->timenow + mDNSPlatformOneSecond;
|
||||
}
|
||||
|
||||
|
||||
// 7. Send Response packets, including probing records just advanced to announcing state
|
||||
if (m->timenow - m->NextScheduledResponse >= 0) SendResponses(m);
|
||||
if (m->timenow - m->NextScheduledResponse >= 0)
|
||||
|
@ -4773,7 +4773,7 @@ mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const m
|
|||
DNSQuestion q;
|
||||
ptr = getQuestion(query, ptr, end, InterfaceID, &q); // get the question...
|
||||
if (!ptr) return(mDNSNULL);
|
||||
|
||||
|
||||
for (rr=ResponseRecords; rr; rr=rr->NextResponse) // and search our list of proposed answers
|
||||
{
|
||||
if (rr->NR_AnswerTo == ptr) // If we're going to generate a record answering this question
|
||||
|
@ -4784,7 +4784,7 @@ mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const m
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (response->h.numQuestions == 0) { LogMsg("GenerateUnicastResponse: ERROR! Why no questions?"); return(mDNSNULL); }
|
||||
}
|
||||
|
||||
|
@ -4834,7 +4834,7 @@ mDNSlocal int CompareRData(AuthRecord *our, CacheRecord *pkt)
|
|||
if (pktptr >= pktend) return(+1); // Packet data ran out first; We won
|
||||
if (*pktptr > *ourptr) return(-1); // Our data is numerically lower; We lost
|
||||
if (*pktptr < *ourptr) return(+1); // Packet data is numerically lower; We won
|
||||
|
||||
|
||||
debugf("CompareRData: How did we get here?");
|
||||
return(-1);
|
||||
}
|
||||
|
@ -5007,7 +5007,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
|
|||
QuestionNeedsMulticastResponse = QueryWasMulticast && !LegacyQuery && !(pktq.qclass & kDNSQClass_UnicastResponse);
|
||||
// Clear the UnicastResponse flag -- don't want to confuse the rest of the code that follows later
|
||||
pktq.qclass &= ~kDNSQClass_UnicastResponse;
|
||||
|
||||
|
||||
// Note: We use the m->CurrentRecord mechanism here because calling ResolveSimultaneousProbe
|
||||
// can result in user callbacks which may change the record list and/or question list.
|
||||
// Also note: we just mark potential answer records here, without trying to build the
|
||||
|
@ -5072,7 +5072,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
|
|||
rr->MPExpectingKA = mDNStrue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if this question is the same as any of mine.
|
||||
// We only do this for non-truncated queries. Right now it would be too complicated to try
|
||||
// to keep track of duplicate suppression state between multiple packets, especially when we
|
||||
|
@ -5106,7 +5106,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
|
|||
|
||||
if (rr->Additional2 && ResourceRecordIsValidInterfaceAnswer(rr->Additional2, InterfaceID))
|
||||
AddRecordToResponseList(&nrp, rr->Additional2, rr);
|
||||
|
||||
|
||||
// For SRV records, automatically add the Address record(s) for the target host
|
||||
if (rr->resrec.rrtype == kDNSType_SRV)
|
||||
for (rr2=m->ResourceRecords; rr2; rr2=rr2->next) // Scan list of resource records
|
||||
|
@ -5172,7 +5172,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
|
|||
{ *eap = rr->NextInKAList; rr->NextInKAList = mDNSNULL; }
|
||||
else eap = &rr->NextInKAList;
|
||||
}
|
||||
|
||||
|
||||
// See if this Known-Answer is a surprise to us. If so, we shouldn't suppress our own query.
|
||||
if (!ourcacherr)
|
||||
{
|
||||
|
@ -5202,14 +5202,14 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
|
|||
if (rr->NR_AnswerTo)
|
||||
{
|
||||
mDNSBool SendMulticastResponse = mDNSfalse;
|
||||
|
||||
|
||||
// If it's been a while since we multicast this, then send a multicast response for conflict detection, etc.
|
||||
if (m->timenow - (rr->LastMCTime + TicksTTL(rr)/4) >= 0) SendMulticastResponse = mDNStrue;
|
||||
|
||||
|
||||
// If the client insists on a multicast response, then we'd better send one
|
||||
if (rr->NR_AnswerTo == (mDNSu8*)~0) SendMulticastResponse = mDNStrue;
|
||||
else if (rr->NR_AnswerTo) HaveUnicastAnswer = mDNStrue;
|
||||
|
||||
|
||||
if (SendMulticastResponse)
|
||||
{
|
||||
// If we're already planning to send this on another interface, just send it on all interfaces
|
||||
|
@ -5292,14 +5292,14 @@ exit:
|
|||
rr->NR_AnswerTo = mDNSNULL;
|
||||
rr->NR_AdditionalTo = mDNSNULL;
|
||||
}
|
||||
|
||||
|
||||
while (ExpectedAnswers)
|
||||
{
|
||||
CacheRecord *rr;
|
||||
rr = ExpectedAnswers;
|
||||
ExpectedAnswers = rr->NextInKAList;
|
||||
rr->NextInKAList = mDNSNULL;
|
||||
|
||||
|
||||
// For non-truncated queries, we can definitively say that we should expect
|
||||
// to be seeing a response for any records still left in the ExpectedAnswers list
|
||||
if (!(query->h.flags.b[0] & kDNSFlag0_TC))
|
||||
|
@ -5337,7 +5337,7 @@ exit:
|
|||
mDNSu32 remain = (mDNSu32)(RRExpireTime(rr) - m->timenow) / 4;
|
||||
if (remain > 240 * (mDNSu32)mDNSPlatformOneSecond)
|
||||
remain = 240 * (mDNSu32)mDNSPlatformOneSecond;
|
||||
|
||||
|
||||
// Only show debugging message if this record was not about to expire anyway
|
||||
if (RRExpireTime(rr) - m->timenow > 4 * mDNSPlatformOneSecond)
|
||||
debugf("ProcessQuery: (MPQ) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
|
||||
|
@ -5348,13 +5348,13 @@ exit:
|
|||
rr->MPUnansweredQ = 0; // Clear MPQ/MPKA statistics
|
||||
rr->MPUnansweredKA = 0;
|
||||
rr->MPExpectingKA = mDNSfalse;
|
||||
|
||||
|
||||
if (remain < kDefaultReconfirmTimeForNoAnswer)
|
||||
remain = kDefaultReconfirmTimeForNoAnswer;
|
||||
mDNS_Reconfirm_internal(m, rr, remain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (DupQuestions)
|
||||
{
|
||||
int i;
|
||||
|
@ -5365,7 +5365,7 @@ exit:
|
|||
debugf("ProcessQuery: Recorded DSI for %##s (%s) on %p/%s %d", q->qname.c, DNSTypeName(q->qtype), InterfaceID,
|
||||
srcaddr->type == mDNSAddrType_IPv4 ? "v4" : "v6", i);
|
||||
}
|
||||
|
||||
|
||||
return(responseptr);
|
||||
}
|
||||
|
||||
|
@ -5375,7 +5375,7 @@ mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg,
|
|||
{
|
||||
DNSMessage response;
|
||||
const mDNSu8 *responseend = mDNSNULL;
|
||||
|
||||
|
||||
verbosedebugf("Received Query from %#-15a:%d to %#-15a:%d on 0x%.8X with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
|
||||
srcaddr, (mDNSu16)srcport.b[0]<<8 | srcport.b[1],
|
||||
dstaddr, (mDNSu16)dstport.b[0]<<8 | dstport.b[1],
|
||||
|
@ -5384,7 +5384,7 @@ mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg,
|
|||
msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
|
||||
msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
|
||||
msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s");
|
||||
|
||||
|
||||
responseend = ProcessQuery(m, msg, end, srcaddr, InterfaceID,
|
||||
(srcport.NotAnInteger != MulticastDNSPort.NotAnInteger), mDNSAddrIsDNSMulticast(dstaddr), &response);
|
||||
|
||||
|
@ -5410,7 +5410,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
|
|||
const mDNSu8 *ptr = LocateAnswers(response, end); // We ignore questions (if any) in a DNS response packet
|
||||
CacheRecord *CacheFlushRecords = mDNSNULL;
|
||||
CacheRecord **cfp = &CacheFlushRecords;
|
||||
|
||||
|
||||
// All records in a DNS response packet are treated as equally valid statements of truth. If we want
|
||||
// to guard against spoof responses, then the only credible protection against that is cryptographic
|
||||
// security, e.g. DNSSEC., not worring about which section in the spoof packet contained the record
|
||||
|
@ -5542,7 +5542,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
|
|||
verbosedebugf("Found record size %5d interface %p already in cache: %s",
|
||||
pkt.r.resrec.rdlength, InterfaceID, GetRRDisplayString(m, &pkt.r));
|
||||
rr->TimeRcvd = m->timenow;
|
||||
|
||||
|
||||
if (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask)
|
||||
{
|
||||
// If this packet record has the kDNSClass_UniqueRRSet flag set, then add it to our cache flushing list
|
||||
|
@ -5647,20 +5647,20 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNS
|
|||
const mDNSu8 StdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery;
|
||||
const mDNSu8 StdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery;
|
||||
const mDNSu8 QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
|
||||
|
||||
|
||||
// Read the integer parts which are in IETF byte-order (MSB first, LSB second)
|
||||
mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
|
||||
msg->h.numQuestions = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
|
||||
msg->h.numAnswers = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]);
|
||||
msg->h.numAuthorities = (mDNSu16)((mDNSu16)ptr[4] << 8 | ptr[5]);
|
||||
msg->h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] << 8 | ptr[7]);
|
||||
|
||||
|
||||
if (!m) { LogMsg("mDNSCoreReceive ERROR m is NULL"); return; }
|
||||
|
||||
|
||||
// We use zero addresses and all-ones addresses at various places in the code to indicate special values like "no address"
|
||||
// If we accept and try to process a packet with zero or all-ones source address, that could really mess things up
|
||||
if (!mDNSAddressIsValid(srcaddr)) { debugf("mDNSCoreReceive ignoring packet from %#a", srcaddr); return; }
|
||||
|
||||
|
||||
mDNS_Lock(m);
|
||||
if (QR_OP == StdQ) mDNSCoreReceiveQuery (m, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID);
|
||||
else if (QR_OP == StdR) mDNSCoreReceiveResponse(m, msg, end, srcaddr, dstaddr, InterfaceID, ttl);
|
||||
|
@ -5999,7 +5999,7 @@ mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const Reso
|
|||
{
|
||||
ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
|
||||
if (!AddRecord) return;
|
||||
|
||||
|
||||
if (answer->rrtype == kDNSType_A)
|
||||
{
|
||||
query->info->ip.type = mDNSAddrType_IPv4;
|
||||
|
@ -6154,7 +6154,7 @@ mDNSexport void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mD
|
|||
|
||||
rr->resrec.RecordType = RecordType;
|
||||
rr->HostTarget = mDNSfalse;
|
||||
|
||||
|
||||
// Field Group 2: Transient state for Authoritative Records (set in mDNS_Register_internal)
|
||||
// Field Group 3: Transient state for Cache Records (set in mDNS_Register_internal)
|
||||
|
||||
|
@ -6207,7 +6207,7 @@ mDNSexport mStatus mDNS_Update(mDNS *const m, AuthRecord *const rr, mDNSu32 newt
|
|||
if (rr->UpdateCallback)
|
||||
rr->UpdateCallback(m, rr, n); // ...and let the client free this memory, if necessary
|
||||
}
|
||||
|
||||
|
||||
if (rr->AnnounceCount < ReannounceCount)
|
||||
rr->AnnounceCount = ReannounceCount;
|
||||
rr->ThisAPInterval = DefaultAPIntervalForRecordType(rr->resrec.RecordType);
|
||||
|
@ -6258,7 +6258,7 @@ mDNSlocal void mDNS_AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
|
|||
char buffer[256];
|
||||
NetworkInterfaceInfo *primary = FindFirstAdvertisedInterface(m);
|
||||
if (!primary) primary = set; // If no existing advertised interface, this new NetworkInterfaceInfo becomes our new primary
|
||||
|
||||
|
||||
mDNS_SetupResourceRecord(&set->RR_A, mDNSNULL, set->InterfaceID, kDNSType_A, kDefaultTTLforUnique, kDNSRecordTypeUnique, HostNameCallback, set);
|
||||
mDNS_SetupResourceRecord(&set->RR_PTR, mDNSNULL, set->InterfaceID, kDNSType_PTR, kDefaultTTLforUnique, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
|
||||
mDNS_SetupResourceRecord(&set->RR_HINFO, mDNSNULL, set->InterfaceID, kDNSType_HINFO, kDefaultTTLforUnique, kDNSRecordTypeUnique, mDNSNULL, mDNSNULL);
|
||||
|
@ -6422,7 +6422,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
|
|||
mDNSBool FirstOfType = mDNStrue;
|
||||
NetworkInterfaceInfo **p = &m->HostInterfaces;
|
||||
mDNS_Lock(m);
|
||||
|
||||
|
||||
// Assume this interface will be active
|
||||
set->InterfaceActive = mDNStrue;
|
||||
set->IPv4Available = (set->ip.type == mDNSAddrType_IPv4 && set->TxAndRx);
|
||||
|
@ -6451,7 +6451,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
|
|||
|
||||
set->next = mDNSNULL;
|
||||
*p = set;
|
||||
|
||||
|
||||
debugf("mDNS_RegisterInterface: InterfaceID %p %#a %s", set->InterfaceID, &set->ip,
|
||||
set->InterfaceActive ?
|
||||
"not represented in list; marking active and retriggering queries" :
|
||||
|
@ -6477,7 +6477,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
|
|||
q->RecentAnswers = 0;
|
||||
if (ActiveQuestion(q)) m->NextScheduledQuery = m->timenow;
|
||||
}
|
||||
|
||||
|
||||
// For all our non-specific authoritative resource records (and any dormant records specific to this interface)
|
||||
// we now need them to re-probe if necessary, and then re-announce.
|
||||
for (rr = m->ResourceRecords; rr; rr=rr->next)
|
||||
|
@ -6505,7 +6505,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
|
|||
mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set)
|
||||
{
|
||||
NetworkInterfaceInfo **p = &m->HostInterfaces;
|
||||
|
||||
|
||||
mDNSBool revalidate = mDNSfalse;
|
||||
// If this platform has the "phantom interfaces" known bug (e.g. Jaguar), we have to revalidate records every
|
||||
// time an interface goes away. Otherwise, when you disconnect the Ethernet cable, the system reports that it
|
||||
|
@ -6542,7 +6542,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
|
|||
set->InterfaceID);
|
||||
intf->InterfaceActive = mDNStrue;
|
||||
UpdateInterfaceProtocols(m, intf);
|
||||
|
||||
|
||||
// See if another representative *of the same type* exists. If not, we mave have gone from
|
||||
// dual-stack to v6-only (or v4-only) so we need to reconfirm which records are still valid.
|
||||
for (intf = m->HostInterfaces; intf; intf = intf->next)
|
||||
|
@ -6617,7 +6617,7 @@ mDNSlocal void ServiceCallback(mDNS *const m, AuthRecord *const rr, mStatus resu
|
|||
mDNS_DeregisterService(m, sr); // Unlink the records from our list
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (result == mStatus_MemFree)
|
||||
{
|
||||
// If the PTR record or any of the subtype PTR record are still in the process of deregistering,
|
||||
|
@ -6662,13 +6662,13 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
|
|||
sr->Conflict = mDNSfalse;
|
||||
if (host && host->c[0]) sr->Host = *host;
|
||||
else sr->Host.c[0] = 0;
|
||||
|
||||
|
||||
// Initialize the AuthRecord objects to sane values
|
||||
mDNS_SetupResourceRecord(&sr->RR_ADV, mDNSNULL, InterfaceID, kDNSType_PTR, kDefaultTTLforShared, kDNSRecordTypeAdvisory, ServiceCallback, sr);
|
||||
mDNS_SetupResourceRecord(&sr->RR_PTR, mDNSNULL, InterfaceID, kDNSType_PTR, kDefaultTTLforShared, kDNSRecordTypeShared, ServiceCallback, sr);
|
||||
mDNS_SetupResourceRecord(&sr->RR_SRV, mDNSNULL, InterfaceID, kDNSType_SRV, kDefaultTTLforUnique, kDNSRecordTypeUnique, ServiceCallback, sr);
|
||||
mDNS_SetupResourceRecord(&sr->RR_TXT, mDNSNULL, InterfaceID, kDNSType_TXT, kDefaultTTLforUnique, kDNSRecordTypeUnique, ServiceCallback, sr);
|
||||
|
||||
|
||||
// If the client is registering an oversized TXT record,
|
||||
// it is the client's responsibility to alloate a ServiceRecordSet structure that is large enough for it
|
||||
if (sr->RR_TXT.resrec.rdata->MaxRDLength < txtlen)
|
||||
|
@ -6682,7 +6682,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
|
|||
if (ConstructServiceName(&sr->RR_PTR.resrec.name, mDNSNULL, type, domain) == mDNSNULL) return(mStatus_BadParamErr);
|
||||
if (ConstructServiceName(&sr->RR_SRV.resrec.name, name, type, domain) == mDNSNULL) return(mStatus_BadParamErr);
|
||||
AssignDomainName(sr->RR_TXT.resrec.name, sr->RR_SRV.resrec.name);
|
||||
|
||||
|
||||
// 1. Set up the ADV record rdata to advertise our service type
|
||||
AssignDomainName(sr->RR_ADV.resrec.rdata->u.name, sr->RR_PTR.resrec.name);
|
||||
|
||||
|
@ -6756,9 +6756,9 @@ mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
|
|||
mDNS_SetupResourceRecord(&extra->r, rdata, sr->RR_PTR.resrec.InterfaceID, extra->r.resrec.rrtype, ttl, kDNSRecordTypeUnique, ServiceCallback, sr);
|
||||
AssignDomainName(extra->r.resrec.name, sr->RR_SRV.resrec.name);
|
||||
extra->r.DependentOn = &sr->RR_SRV;
|
||||
|
||||
|
||||
debugf("mDNS_AddRecordToService adding record to %##s", extra->r.resrec.name.c);
|
||||
|
||||
|
||||
result = mDNS_Register(m, &extra->r);
|
||||
if (!result) *e = extra;
|
||||
return result;
|
||||
|
@ -6775,7 +6775,7 @@ mDNSexport mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet
|
|||
}
|
||||
|
||||
debugf("mDNS_RemoveRecordFromService removing record from %##s", extra->r.resrec.name.c);
|
||||
|
||||
|
||||
*e = (*e)->next;
|
||||
return(mDNS_Deregister(m, &extra->r));
|
||||
}
|
||||
|
@ -6796,7 +6796,7 @@ mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordS
|
|||
}
|
||||
debugf("Reregistering as %#s", newname->c);
|
||||
if (sr->RR_SRV.HostTarget == mDNSfalse && sr->Host.c[0]) host = &sr->Host;
|
||||
|
||||
|
||||
err = mDNS_RegisterService(m, sr, newname, &type, &domain,
|
||||
host, sr->RR_SRV.resrec.rdata->u.srv.port, sr->RR_TXT.resrec.rdata->u.txt.c, sr->RR_TXT.resrec.rdlength,
|
||||
sr->SubTypes, sr->NumSubTypes,
|
||||
|
@ -6811,7 +6811,7 @@ mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordS
|
|||
extras = extras->next;
|
||||
err = mDNS_AddRecordToService(m, sr, e, e->r.resrec.rdata, e->r.resrec.rroriginalttl);
|
||||
}
|
||||
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
@ -6837,14 +6837,14 @@ mDNSexport mStatus mDNS_DeregisterService(mDNS *const m, ServiceRecordSet *sr)
|
|||
ExtraResourceRecord *e;
|
||||
mDNS_Lock(m);
|
||||
e = sr->Extras;
|
||||
|
||||
|
||||
// We use mDNS_Dereg_repeat because, in the event of a collision, some or all of the
|
||||
// SRV, TXT, or Extra records could have already been automatically deregistered, and that's okay
|
||||
mDNS_Deregister_internal(m, &sr->RR_SRV, mDNS_Dereg_repeat);
|
||||
mDNS_Deregister_internal(m, &sr->RR_TXT, mDNS_Dereg_repeat);
|
||||
|
||||
|
||||
mDNS_Deregister_internal(m, &sr->RR_ADV, mDNS_Dereg_normal);
|
||||
|
||||
|
||||
// We deregister all of the extra records, but we leave the sr->Extras list intact
|
||||
// in case the client wants to do a RenameAndReregister and reinstate the registration
|
||||
while (e)
|
||||
|
@ -6924,9 +6924,9 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
|
|||
mDNSs32 timenow;
|
||||
mStatus result = mDNSPlatformTimeInit(&timenow);
|
||||
if (result != mStatus_NoError) return(result);
|
||||
|
||||
|
||||
if (!rrcachestorage) rrcachesize = 0;
|
||||
|
||||
|
||||
m->p = p;
|
||||
m->KnownBugs = 0;
|
||||
m->AdvertiseLocalAddresses = AdvertiseLocalAddresses;
|
||||
|
@ -7037,7 +7037,7 @@ mDNSexport void mDNS_Close(mDNS *const m)
|
|||
LogMsg("*** ERROR *** rrcache_active %lu != m->rrcache_active %lu", rrcache_active, m->rrcache_active);
|
||||
|
||||
m->Questions = mDNSNULL; // We won't be answering any more questions!
|
||||
|
||||
|
||||
for (intf = m->HostInterfaces; intf; intf = intf->next)
|
||||
if (intf->Advertise)
|
||||
mDNS_DeadvertiseInterface(m, intf);
|
||||
|
@ -7065,7 +7065,7 @@ mDNSexport void mDNS_Close(mDNS *const m)
|
|||
else
|
||||
while (m->ResourceRecords)
|
||||
SendResponses(m);
|
||||
|
||||
|
||||
mDNS_Unlock(m);
|
||||
debugf("mDNS_Close: mDNSPlatformClose");
|
||||
mDNSPlatformClose(m);
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
|
@ -17,7 +17,7 @@
|
|||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
* Formatting notes:
|
||||
|
@ -146,6 +146,7 @@ First checkin
|
|||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mDNSUNP.h"
|
||||
|
||||
|
@ -481,7 +482,7 @@ static int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interface
|
|||
static const int kOn = 1;
|
||||
static const int kIntTwoFiveFive = 255;
|
||||
static const unsigned char kByteTwoFiveFive = 255;
|
||||
|
||||
|
||||
(void) interfaceIndex; // Unused
|
||||
assert(intfAddr != NULL);
|
||||
assert(sktPtr != NULL);
|
||||
|
@ -576,8 +577,8 @@ static int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interface
|
|||
bindAddr.sin_port = port.NotAnInteger;
|
||||
bindAddr.sin_addr.s_addr = INADDR_ANY; // Want to receive multicasts AND unicasts on this socket
|
||||
err = bind(*sktPtr, (struct sockaddr *) &bindAddr, sizeof(bindAddr));
|
||||
if (err < 0) {
|
||||
err = errno;
|
||||
if (err < 0) {
|
||||
err = errno;
|
||||
DPRINTF(E_LOG,L_REND,"bind: %s\n",strerror(errno));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
|
@ -17,7 +17,7 @@
|
|||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
|
||||
Change History (most recent first):
|
||||
|
@ -91,11 +91,12 @@ First checkin
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
|
||||
/* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
|
||||
other platforms don't even have that include file. So,
|
||||
if we haven't yet got a definition, let's try to find
|
||||
/* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
|
||||
other platforms don't even have that include file. So,
|
||||
if we haven't yet got a definition, let's try to find
|
||||
<sys/sockio.h>.
|
||||
*/
|
||||
|
||||
|
@ -103,7 +104,7 @@ First checkin
|
|||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
/* sockaddr_dl is only referenced if we're using IP_RECVIF,
|
||||
/* sockaddr_dl is only referenced if we're using IP_RECVIF,
|
||||
so only include the header in that case.
|
||||
*/
|
||||
|
||||
|
@ -122,7 +123,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
struct ifreq *ifr, ifrcopy;
|
||||
struct sockaddr_in *sinptr;
|
||||
// int index;
|
||||
|
||||
|
||||
#if defined(AF_INET6) && defined(HAVE_IPV6)
|
||||
struct sockaddr_in6 *sinptr6;
|
||||
#endif
|
||||
|
@ -132,7 +133,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
sockfd = -1;
|
||||
buf = NULL;
|
||||
ifihead = NULL;
|
||||
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) {
|
||||
goto gotError;
|
||||
|
@ -183,9 +184,9 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
|
||||
ptr += sizeof(struct ifreq); /* for next one in buffer */
|
||||
#endif
|
||||
|
||||
|
||||
DPRINTF(E_DBG,L_REND,"intf name=%s AF=%d, flags=%08x\n", ifr->ifr_name, ifr->ifr_addr.sa_family,ifr->ifr_flags);
|
||||
|
||||
|
||||
if (ifr->ifr_addr.sa_family != family)
|
||||
continue; /* ignore if not desired address family */
|
||||
|
||||
|
@ -203,7 +204,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
|
||||
flags = ifrcopy.ifr_flags;
|
||||
if ((flags & IFF_UP) == 0)
|
||||
continue; /* ignore if interface not up */
|
||||
|
@ -270,7 +271,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
if (ifi->ifi_addr == NULL) {
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
|
||||
/* Some platforms (*BSD) inject the prefix in IPv6LL addresses */
|
||||
/* We need to strip that out */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
|
||||
|
@ -285,7 +286,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
|||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
|
||||
gotError:
|
||||
if (ifihead != NULL) {
|
||||
free_ifi_info(ifihead);
|
||||
|
@ -323,7 +324,7 @@ free_ifi_info(struct ifi_info *ifihead)
|
|||
}
|
||||
/* end free_ifi_info */
|
||||
|
||||
ssize_t
|
||||
ssize_t
|
||||
recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp)
|
||||
{
|
||||
|
@ -358,10 +359,10 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
|||
*salenptr = msg.msg_namelen; /* pass back results */
|
||||
if (pktp) {
|
||||
/* 0.0.0.0, i/f = -1 */
|
||||
/* We set the interface to -1 so that the caller can
|
||||
tell whether we returned a meaningful value or
|
||||
just some default. Previously this code just
|
||||
set the value to 0, but I'm concerned that 0
|
||||
/* We set the interface to -1 so that the caller can
|
||||
tell whether we returned a meaningful value or
|
||||
just some default. Previously this code just
|
||||
set the value to 0, but I'm concerned that 0
|
||||
might be a valid interface value.
|
||||
*/
|
||||
memset(pktp, 0, sizeof(struct my_in_pktinfo));
|
||||
|
@ -393,11 +394,11 @@ struct in_pktinfo
|
|||
struct in_addr ipi_addr;
|
||||
};
|
||||
#endif
|
||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||
cmptr->cmsg_type == IP_PKTINFO) {
|
||||
struct in_pktinfo *tmp;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
||||
|
||||
|
||||
tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr = tmp->ipi_addr;
|
||||
|
@ -411,7 +412,7 @@ struct in_pktinfo
|
|||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||
cmptr->cmsg_type == IP_RECVDSTADDR) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
||||
|
||||
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
|
||||
sin->sin_port = 0;
|
||||
|
@ -435,11 +436,11 @@ struct in_pktinfo
|
|||
#endif
|
||||
|
||||
#if defined(IPV6_PKTINFO) && defined(HAVE_IPV6)
|
||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
||||
cmptr->cmsg_type == IPV6_PKTINFO) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
|
||||
struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
|
||||
|
||||
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_addr = ip6_info->ipi6_addr;
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "configfile.h"
|
||||
#include "err.h"
|
||||
|
@ -578,6 +580,7 @@ int main(int argc, char *argv[]) {
|
|||
DPRINTF(E_LOG,L_MAIN|L_DB|L_SCAN,"Scanned %d songs (was %d) in "
|
||||
"%d seconds\n",song_count,old_song_count,
|
||||
time(NULL)-start_time);
|
||||
conf_dispose_array(mp3_dir_array);
|
||||
}
|
||||
|
||||
os_wait(MAIN_SLEEP_INTERVAL);
|
||||
|
@ -610,6 +613,7 @@ int main(int argc, char *argv[]) {
|
|||
DPRINTF(E_LOG,L_MAIN,"Done!\n");
|
||||
|
||||
os_deinit();
|
||||
mem_dump();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
* memory debugging
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "err.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef DEBUG_MEM
|
||||
typedef struct debugnode_t {
|
||||
char *file;
|
||||
int line;
|
||||
int size;
|
||||
void *ptr;
|
||||
struct debugnode_t *next;
|
||||
} DEBUGNODE;
|
||||
|
||||
DEBUGNODE _debug_memlist = { NULL, 0, 0, NULL, NULL };
|
||||
|
||||
void debug_free(char *file, int line, void *ptr);
|
||||
void *debug_malloc(char *file, int line, size_t size);
|
||||
void *debug_realloc(char *file, int line, void *ptr, size_t size);
|
||||
void *debug_calloc(char *file, int line, size_t count, size_t size);
|
||||
char *debug_strdup(char *file, int line, const char *str);
|
||||
void debug_dump(void);
|
||||
|
||||
/**
|
||||
* find a ptr in the node list, assuming the list is already
|
||||
* locked.
|
||||
*/
|
||||
DEBUGNODE *_debug_find_ptr(void *ptr) {
|
||||
DEBUGNODE *prev, *current;
|
||||
|
||||
prev = &_debug_memlist;
|
||||
current = prev->next;
|
||||
|
||||
while(current) {
|
||||
if(current->ptr == ptr)
|
||||
return current;
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *_debug_alloc_nolock(char *file, int line, int size) {
|
||||
DEBUGNODE *pnew;
|
||||
|
||||
pnew = (DEBUGNODE *)malloc(sizeof(DEBUGNODE));
|
||||
if(!pnew)
|
||||
DPRINTF(E_FATAL,L_MISC,"Malloc failed in _debug_alloc\n");
|
||||
|
||||
pnew->file = strdup(file);
|
||||
pnew->line = line;
|
||||
pnew->size = size;
|
||||
pnew->ptr = malloc(size);
|
||||
|
||||
if(!pnew->ptr)
|
||||
DPRINTF(E_FATAL,L_MISC,"Malloc failed in _debug_alloc\n");
|
||||
|
||||
pnew->next = _debug_memlist.next;
|
||||
_debug_memlist.next = pnew;
|
||||
|
||||
return pnew->ptr;
|
||||
}
|
||||
|
||||
void *_debug_alloc(char *file, int line, int size) {
|
||||
void *ptr;
|
||||
|
||||
util_mutex_lock(l_memdebug);
|
||||
ptr = _debug_alloc_nolock(file, line, size);
|
||||
util_mutex_unlock(l_memdebug);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void debug_dump(void) {
|
||||
DEBUGNODE *current;
|
||||
uint32_t size = 0;
|
||||
int blocks = 0;
|
||||
|
||||
if(!_debug_memlist.next) {
|
||||
DPRINTF(E_LOG,L_MISC,"No leaked memory!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
current = _debug_memlist.next;
|
||||
while(current) {
|
||||
size += current->size;
|
||||
blocks++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
DPRINTF(E_WARN,L_MISC,"Leaked %d bytes in %d blocks\n",size, blocks);
|
||||
current = _debug_memlist.next;
|
||||
while(current) {
|
||||
DPRINTF(E_WARN,L_MISC,"%d bytes: %s, line %d\n", current->size,
|
||||
current->file, current->line);
|
||||
util_hexdump(current->ptr,current->size);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void debug_free(char *file, int line, void *ptr) {
|
||||
DEBUGNODE *prev, *current;
|
||||
|
||||
util_mutex_lock(l_memdebug);
|
||||
prev = &_debug_memlist;
|
||||
current = prev->next;
|
||||
|
||||
while(current) {
|
||||
if(current->ptr == ptr) {
|
||||
/* found it */
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if(!current) {
|
||||
util_mutex_unlock(l_memdebug);
|
||||
DPRINTF(E_FATAL,L_MISC,"Attempt to free an unallocated ptr: %s, %d\n",
|
||||
file, line);
|
||||
}
|
||||
|
||||
prev->next = current->next;
|
||||
util_mutex_unlock(l_memdebug);
|
||||
|
||||
if(current) {
|
||||
if(current->file)
|
||||
free(current->file);
|
||||
if(current->ptr)
|
||||
free(current->ptr);
|
||||
free(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void *debug_malloc(char *file, int line, size_t size) {
|
||||
void *ptr;
|
||||
|
||||
ptr = _debug_alloc(file,line,size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *debug_realloc(char *file, int line, void *ptr, size_t size) {
|
||||
void *new_ptr;
|
||||
DEBUGNODE *old_node;
|
||||
int copy_size;
|
||||
|
||||
util_mutex_lock(l_memdebug);
|
||||
old_node = _debug_find_ptr(ptr);
|
||||
if(!old_node) {
|
||||
util_mutex_unlock(l_memdebug);
|
||||
DPRINTF(E_FATAL,L_MISC,"Attempt to realloc invalid ptr: %s, %d\n",
|
||||
file, line);
|
||||
}
|
||||
|
||||
new_ptr = _debug_alloc_nolock(file, line, size);
|
||||
util_mutex_unlock(l_memdebug);
|
||||
|
||||
copy_size = old_node->size;
|
||||
if(size < copy_size)
|
||||
copy_size=size;
|
||||
|
||||
memcpy(new_ptr,old_node->ptr,copy_size);
|
||||
debug_free(file, line, old_node->ptr);
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void *debug_calloc(char *file, int line, size_t count, size_t size) {
|
||||
void *ptr;
|
||||
|
||||
ptr = debug_malloc(file, line, count * size);
|
||||
memset(ptr,0,count *size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *debug_strdup(char *file, int line, const char *str) {
|
||||
void *ptr;
|
||||
int size;
|
||||
|
||||
size = strlen(str);
|
||||
ptr = debug_malloc(file, line, size + 1);
|
||||
strcpy(ptr,str);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* $Id: $
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_MEM
|
||||
# define free(ptr) debug_free(__FILE__,__LINE__,(ptr))
|
||||
# define malloc(size) debug_malloc(__FILE__,__LINE__,(size))
|
||||
# define realloc(ptr, size) debug_realloc(__FILE__,__LINE__,(ptr),(size))
|
||||
# define calloc(count,size) debug_calloc(__FILE__,__LINE__,(count),(size))
|
||||
# define strdup(str) debug_strdup(__FILE__,__LINE__,(str))
|
||||
# define mem_dump() debug_dump()
|
||||
|
||||
extern void debug_free(char *file, int line, void *ptr);
|
||||
extern void *debug_malloc(char *file, int line, size_t size);
|
||||
extern void *debug_realloc(char *file, int line, void *ptr, size_t size);
|
||||
extern void *debug_calloc(char *file, int line, size_t count, size_t size);
|
||||
extern void *debug_strdup(char *file, int line, const char *str);
|
||||
extern void debug_dump(void);
|
||||
#else
|
||||
# define mem_dump()
|
||||
#endif
|
||||
|
||||
|
|
@ -46,8 +46,8 @@
|
|||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "db-generic.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
|
|
@ -52,9 +52,9 @@
|
|||
#include "CoreFoundation/CoreFoundation.h"
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "daapd.h"
|
||||
#include "os.h"
|
||||
|
||||
/** You say po-tay-to, I say po-tat-o */
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "db-generic.h"
|
||||
#include "err.h"
|
||||
#include "smart-parser.h"
|
||||
#include "daapd.h"
|
||||
|
||||
CONFIG config;
|
||||
char *scan_winamp_genre[] = { NULL };
|
||||
|
@ -57,7 +57,7 @@ int main(int argc, char *argv[]) {
|
|||
fprintf(stderr,"could not read config file: %s\n",configfile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if(debuglevel) {
|
||||
printf("Setting debug level to %d\n",debuglevel);
|
||||
err_setlevel(debuglevel);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "configfile.h"
|
||||
#include "db-generic.h"
|
||||
|
|
|
@ -33,6 +33,8 @@ static char rcsid[]="$Id$";
|
|||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "redblack.h"
|
||||
|
||||
#define assert(expr)
|
||||
|
@ -152,7 +154,7 @@ RB_STATIC struct RB_ENTRY(tree) *RB_ENTRY(init)(void)
|
|||
|
||||
if ((retval=(struct RB_ENTRY(tree) *) malloc(sizeof(struct RB_ENTRY(tree))))==NULL)
|
||||
return(NULL);
|
||||
|
||||
|
||||
#ifndef RB_CUSTOMIZE
|
||||
retval->rb_cmp=cmp;
|
||||
retval->rb_config=config;
|
||||
|
@ -171,7 +173,7 @@ RB_ENTRY(destroy)(struct RB_ENTRY(tree) *rbinfo)
|
|||
|
||||
if (rbinfo->rb_root!=RBNULL)
|
||||
RB_ENTRY(_destroy)(rbinfo->rb_root);
|
||||
|
||||
|
||||
free(rbinfo);
|
||||
}
|
||||
#endif /* no_destroy */
|
||||
|
@ -192,7 +194,7 @@ RB_ENTRY(search)(const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *rbinfo)
|
|||
#endif /* no_search */
|
||||
|
||||
#ifndef no_find
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_ENTRY(find)(const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *rbinfo)
|
||||
{
|
||||
struct RB_ENTRY(node) *x;
|
||||
|
@ -211,7 +213,7 @@ RB_ENTRY(find)(const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *rbinfo)
|
|||
#endif /* no_find */
|
||||
|
||||
#ifndef no_delete
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_ENTRY(delete)(const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *rbinfo)
|
||||
{
|
||||
struct RB_ENTRY(node) *x;
|
||||
|
@ -257,7 +259,7 @@ RB_ENTRY(openlist)(const struct RB_ENTRY(tree) *rbinfo)
|
|||
return(RB_ENTRY(_openlist)(rbinfo->rb_root));
|
||||
}
|
||||
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_ENTRY(readlist)(RBLIST *rblistp)
|
||||
{
|
||||
if (rblistp==NULL)
|
||||
|
@ -277,7 +279,7 @@ RB_ENTRY(closelist)(RBLIST *rblistp)
|
|||
#endif /* no_readlist */
|
||||
|
||||
#ifndef no_lookup
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_STATIC const RB_ENTRY(data_t) *
|
||||
RB_ENTRY(lookup)(int mode, const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *rbinfo)
|
||||
{
|
||||
struct RB_ENTRY(node) *x;
|
||||
|
@ -502,10 +504,10 @@ RB_ENTRY(_lookup)(int mode, const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *
|
|||
|
||||
if (found && (mode==RB_LUEQUAL || mode==RB_LUGTEQ || mode==RB_LULTEQ))
|
||||
return(x);
|
||||
|
||||
|
||||
if (!found && (mode==RB_LUEQUAL || mode==RB_LUNEXT || mode==RB_LUPREV))
|
||||
return(RBNULL);
|
||||
|
||||
|
||||
if (mode==RB_LUGTEQ || (!found && mode==RB_LUGREAT))
|
||||
{
|
||||
if (cmp>0)
|
||||
|
@ -527,7 +529,7 @@ RB_ENTRY(_lookup)(int mode, const RB_ENTRY(data_t) *key, struct RB_ENTRY(tree) *
|
|||
|
||||
if (mode==RB_LUPREV || (found && mode==RB_LULESS))
|
||||
return(RB_ENTRY(_predecessor)(x));
|
||||
|
||||
|
||||
/* Shouldn't get here */
|
||||
return(RBNULL);
|
||||
}
|
||||
|
@ -893,7 +895,7 @@ RB_ENTRY(_openlist)(const struct RB_ENTRY(node) *rootp)
|
|||
return(rblistp);
|
||||
}
|
||||
|
||||
static const RB_ENTRY(data_t) *
|
||||
static const RB_ENTRY(data_t) *
|
||||
RB_ENTRY(_readlist)(RBLIST *rblistp)
|
||||
{
|
||||
const RB_ENTRY(data_t) *key=NULL;
|
||||
|
@ -1026,7 +1028,7 @@ RB_ENTRY(_check1)(struct RB_ENTRY(node) *x)
|
|||
|
||||
if (rb_check1(x->left))
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (x->right != RBNULL)
|
||||
{
|
||||
|
@ -1038,7 +1040,7 @@ RB_ENTRY(_check1)(struct RB_ENTRY(node) *x)
|
|||
|
||||
if (rb_check1(x->right))
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1087,7 +1089,7 @@ RB_ENTRY(dumptree)(struct RB_ENTRY(node) *x, int n)
|
|||
|
||||
RB_ENTRY(dumptree)(x->left, n);
|
||||
RB_ENTRY(dumptree)(x->right, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <avahi-common/timeval.h>
|
||||
#include <avahi-common/malloc.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
|
||||
static AvahiClient *mdns_client = NULL;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <howl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "os-unix.h"
|
||||
#include "rend-unix.h"
|
||||
|
@ -79,11 +80,11 @@ int rend_private_init(char *user) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if(os_drop_privs(user))
|
||||
if(os_drop_privs(user))
|
||||
return -1;
|
||||
|
||||
DPRINTF(E_DBG,L_REND,"Starting polling thread\n");
|
||||
|
||||
|
||||
if(pthread_create(&rend_tid,NULL,rend_pipe_monitor,NULL)) {
|
||||
DPRINTF(E_FATAL,L_REND,"Could not start thread. Terminating\n");
|
||||
/* should kill parent, too */
|
||||
|
@ -129,7 +130,7 @@ void *rend_pipe_monitor(void* arg) {
|
|||
/*
|
||||
* rend_callback
|
||||
*
|
||||
* This gets called from the main thread when there is a
|
||||
* This gets called from the main thread when there is a
|
||||
* message waiting to be processed.
|
||||
*/
|
||||
void rend_callback(void) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "dns_sd.h"
|
||||
#include "err.h"
|
||||
|
||||
|
@ -28,7 +29,7 @@ static volatile int rend_stop_flag = 0;
|
|||
//static volatile int rend_timeout = 100000000; /* select timeout */
|
||||
static volatile int rend_timeout=2;
|
||||
static volatile int rend_count=0;
|
||||
static pthread_mutex_t rend_mutex=PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t rend_mutex=PTHREAD_MUTEX_INITIALIZER;
|
||||
typedef struct tag_rend_entry {
|
||||
DNSServiceRef client;
|
||||
struct tag_rend_entry *next;
|
||||
|
@ -37,9 +38,9 @@ static REND_ENTRY rend_clients = { NULL, NULL };
|
|||
|
||||
/* Forwards */
|
||||
void *rend_mainthread(void *arg);
|
||||
void DNSSD_API rend_reg_reply(DNSServiceRef client, const DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode, const char *name,
|
||||
const char *regtype, const char *domain, void *context);
|
||||
void DNSSD_API rend_reg_reply(DNSServiceRef client, const DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode, const char *name,
|
||||
const char *regtype, const char *domain, void *context);
|
||||
|
||||
/* Typedefs */
|
||||
typedef union { unsigned char b[2]; unsigned short NotAnInteger; } Opaque16;
|
||||
|
@ -95,7 +96,7 @@ void *rend_mainthread(void *arg) {
|
|||
|
||||
FD_SET(DNSServiceRefSockFD(current->client),&readfds);
|
||||
}
|
||||
current = current->next;
|
||||
current = current->next;
|
||||
}
|
||||
rend_unlock();
|
||||
|
||||
|
@ -117,13 +118,13 @@ void *rend_mainthread(void *arg) {
|
|||
}
|
||||
rend_unlock();
|
||||
|
||||
if (err) {
|
||||
DPRINTF(E_LOG,L_REND,"DNSServiceProcessResult returned %d\n", err);
|
||||
rend_stop_flag = 1;
|
||||
if (err) {
|
||||
DPRINTF(E_LOG,L_REND,"DNSServiceProcessResult returned %d\n", err);
|
||||
rend_stop_flag = 1;
|
||||
}
|
||||
} else if (result == 0) {
|
||||
DPRINTF(E_SPAM,L_REND,"rendezvous: tick!\n");
|
||||
|
||||
|
||||
// myTimerCallBack();
|
||||
} else {
|
||||
DPRINTF(E_INF,L_REND,"select() returned %d errno %d %s\n", result, errno, strerror(errno));
|
||||
|
@ -135,7 +136,7 @@ void *rend_mainthread(void *arg) {
|
|||
while(current) {
|
||||
if(current->client)
|
||||
DNSServiceRefDeallocate(current->client);
|
||||
current = current->next;
|
||||
current = current->next;
|
||||
}
|
||||
rend_unlock();
|
||||
return NULL;
|
||||
|
@ -191,7 +192,7 @@ int rend_register(char *name, char *type, int port, char *iface, char *txt) {
|
|||
|
||||
DNSServiceRegister(&pnew->client,0,kDNSServiceInterfaceIndexAny,name,type,"local",NULL,
|
||||
port_netorder,(uint16_t)strlen(txt),txt,rend_reg_reply, NULL);
|
||||
|
||||
|
||||
/* throw off a new thread work this */
|
||||
if(!rend_count) {
|
||||
if((err=pthread_create(&rend_tid,NULL,rend_mainthread,NULL))) {
|
||||
|
@ -205,19 +206,19 @@ int rend_register(char *name, char *type, int port, char *iface, char *txt) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DNSSD_API rend_reg_reply(DNSServiceRef client, const DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode, const char *name,
|
||||
const char *regtype, const char *domain, void *context)
|
||||
void DNSSD_API rend_reg_reply(DNSServiceRef client, const DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode, const char *name,
|
||||
const char *regtype, const char *domain, void *context)
|
||||
{
|
||||
DPRINTF(E_INF,L_REND,"Got a reply for %s.%s%s\n", name, regtype, domain);
|
||||
switch (errorCode) {
|
||||
case kDNSServiceErr_NoError:
|
||||
DPRINTF(E_INF,L_REND,"Name now registered and active\n");
|
||||
DPRINTF(E_INF,L_REND,"Name now registered and active\n");
|
||||
break;
|
||||
case kDNSServiceErr_NameConflict:
|
||||
DPRINTF(E_FATAL,L_REND,"Rendezvous name in use, aborting...\n");
|
||||
case kDNSServiceErr_NameConflict:
|
||||
DPRINTF(E_FATAL,L_REND,"Rendezvous name in use, aborting...\n");
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
DPRINTF(E_FATAL,L_REND,"Error %d\n", errorCode);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
*
|
||||
* ** NOTICE **
|
||||
*
|
||||
* This code is written by (and is therefore copyright) Dr Kay Robbins
|
||||
* (krobbins@cs.utsa.edu) and Dr. Steve Robbins (srobbins@cs.utsa.edu),
|
||||
* and was released with unspecified licensing as part of their book
|
||||
* This code is written by (and is therefore copyright) Dr Kay Robbins
|
||||
* (krobbins@cs.utsa.edu) and Dr. Steve Robbins (srobbins@cs.utsa.edu),
|
||||
* and was released with unspecified licensing as part of their book
|
||||
* _UNIX_Systems_Programming_ (Prentice Hall, ISBN: 0130424110).
|
||||
*
|
||||
* Dr. Steve Robbins was kind enough to allow me to re-license this
|
||||
* software as GPL. I would request that any bugs or problems with
|
||||
* this code be brought to my attention (ron@pedde.com), and I will
|
||||
* Dr. Steve Robbins was kind enough to allow me to re-license this
|
||||
* software as GPL. I would request that any bugs or problems with
|
||||
* this code be brought to my attention (ron@pedde.com), and I will
|
||||
* submit appropriate patches upstream, should the problem be with
|
||||
* the original code.
|
||||
*
|
||||
|
@ -52,6 +52,7 @@
|
|||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "restart.h"
|
||||
|
||||
|
@ -169,7 +170,7 @@ ssize_t readblock(int fd, void *buf, size_t size) {
|
|||
ssize_t bytesread;
|
||||
size_t bytestoread;
|
||||
size_t totalbytes;
|
||||
|
||||
|
||||
for (bufp = buf, bytestoread = size, totalbytes = 0;
|
||||
bytestoread > 0;
|
||||
bufp += bytesread, bytestoread -= bytesread) {
|
||||
|
@ -179,7 +180,7 @@ ssize_t readblock(int fd, void *buf, size_t size) {
|
|||
if (bytesread == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if ((bytesread) == -1 && (errno != EINTR))
|
||||
return -1;
|
||||
if (bytesread == -1)
|
||||
|
@ -207,8 +208,8 @@ int readline(int fd, char *buf, int nbytes) {
|
|||
if (buf[numread-1] == '\n') {
|
||||
buf[numread] = '\0';
|
||||
return numread;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -231,8 +232,8 @@ int readlinetimed(int fd, char *buf, int nbytes, double seconds) {
|
|||
if (buf[numread-1] == '\n') {
|
||||
buf[numread] = '\0';
|
||||
return numread;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -277,11 +278,11 @@ int waitfdtimed(int fd, struct timeval end) {
|
|||
fd_set readset;
|
||||
int retval;
|
||||
struct timeval timeout;
|
||||
|
||||
|
||||
if ((fd < 0) || (fd >= FD_SETSIZE)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
FD_ZERO(&readset);
|
||||
FD_SET(fd, &readset);
|
||||
if (gettimeout(end, &timeout) == -1)
|
||||
|
|
11
src/rxml.c
11
src/rxml.c
|
@ -11,6 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "rxml.h"
|
||||
|
||||
/* Typedefs/Defines */
|
||||
|
@ -125,7 +126,7 @@ int rxml_decode_string(char *string) {
|
|||
* @param handler handler function for events
|
||||
* @param udata opaque data structure to pass to the callback
|
||||
*/
|
||||
int rxml_open(RXMLHANDLE *vp, char *file,
|
||||
int rxml_open(RXMLHANDLE *vp, char *file,
|
||||
RXML_EVTHANDLER handler, void *udata) {
|
||||
RXML *pnew;
|
||||
|
||||
|
@ -232,7 +233,7 @@ int rxml_parse(RXMLHANDLE vp) {
|
|||
|
||||
ph->line = 0;
|
||||
|
||||
|
||||
|
||||
textbuffer[0] = '\0';
|
||||
|
||||
/* walk through and read row by row */
|
||||
|
@ -283,7 +284,7 @@ int rxml_parse(RXMLHANDLE vp) {
|
|||
}
|
||||
}
|
||||
|
||||
in_text=1;
|
||||
in_text=1;
|
||||
text_offset=0;
|
||||
textbuffer[0] = '\0';
|
||||
|
||||
|
@ -298,7 +299,7 @@ int rxml_parse(RXMLHANDLE vp) {
|
|||
ph->udata,tagbuffer);
|
||||
|
||||
/* send a follow-up end on a <tag/> - style tag */
|
||||
if((single_tag) && (ph->handler))
|
||||
if((single_tag) && (ph->handler))
|
||||
ph->handler(RXML_EVT_END,ph->udata,tagbuffer);
|
||||
|
||||
offset++;
|
||||
|
@ -307,7 +308,7 @@ int rxml_parse(RXMLHANDLE vp) {
|
|||
default:
|
||||
if((in_text) && (text_offset < (sizeof(textbuffer)-1))) {
|
||||
/* get rid of EOL */
|
||||
if((linebuffer[offset] != '\r') &&
|
||||
if((linebuffer[offset] != '\r') &&
|
||||
(linebuffer[offset] != '\n')) {
|
||||
textbuffer[text_offset] = linebuffer[offset];
|
||||
text_offset++;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "scan-aac.h"
|
||||
|
@ -50,9 +51,9 @@ time_t scan_aac_mac_to_unix_time(int t);
|
|||
time_t scan_aac_mac_to_unix_time(int t) {
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
|
||||
|
||||
return (t - (365L * 66L * 24L * 60L * 60L + 17L * 60L * 60L * 24L) +
|
||||
(tz.tz_minuteswest * 60));
|
||||
}
|
||||
|
@ -93,12 +94,12 @@ off_t scan_aac_drilltoatom(FILE *aac_fp,char *atom_path,
|
|||
return -1;
|
||||
}
|
||||
strncpy(atom_name, cur_p, 4);
|
||||
atom_offset = scan_aac_findatom(aac_fp, file_size,
|
||||
atom_offset = scan_aac_findatom(aac_fp, file_size,
|
||||
atom_name, atom_length);
|
||||
if (atom_offset == -1) {
|
||||
return -1;
|
||||
}
|
||||
DPRINTF(E_SPAM,L_SCAN,"Found %s atom at off %ld.\n",
|
||||
DPRINTF(E_SPAM,L_SCAN,"Found %s atom at off %ld.\n",
|
||||
atom_name, ftell(aac_fp) - 8);
|
||||
|
||||
cur_p = strchr(cur_p, ':');
|
||||
|
@ -145,7 +146,7 @@ long scan_aac_findatom(FILE *fin, long max_offset,
|
|||
if(size <= 7) /* something not right */
|
||||
return -1;
|
||||
|
||||
if(fread(atom,1,4,fin) != 4)
|
||||
if(fread(atom,1,4,fin) != 4)
|
||||
return -1;
|
||||
|
||||
if(strncasecmp(atom,which_atom,4) == 0) {
|
||||
|
@ -196,7 +197,7 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
atom_offset=scan_aac_drilltoatom(fin, "moov:udta:meta:ilst", &atom_length);
|
||||
if(atom_offset != -1) {
|
||||
/* found the tag section - need to walk through now */
|
||||
|
||||
|
||||
while(current_offset < (long)atom_length) {
|
||||
if(fread((void*)¤t_size,1,sizeof(int),fin) != sizeof(int))
|
||||
break;
|
||||
|
@ -204,13 +205,13 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
DPRINTF(E_SPAM,L_SCAN,"Current size: %d\n");
|
||||
|
||||
current_size=ntohl(current_size);
|
||||
|
||||
|
||||
if(current_size <= 7) /* something not right */
|
||||
break;
|
||||
|
||||
if(fread(current_atom,1,4,fin) != 4)
|
||||
if(fread(current_atom,1,4,fin) != 4)
|
||||
break;
|
||||
|
||||
|
||||
DPRINTF(E_SPAM,L_SCAN,"Current Atom: %c%c%c%c\n",
|
||||
current_atom[0],current_atom[1],current_atom[2],
|
||||
current_atom[3]);
|
||||
|
@ -222,16 +223,16 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
len=current_size-7; /* for ill-formed too-short tags */
|
||||
if(len < 22)
|
||||
len=22;
|
||||
|
||||
|
||||
current_data=(char*)malloc(len); /* extra byte */
|
||||
memset(current_data,0x00,len);
|
||||
|
||||
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
||||
|
||||
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
||||
break;
|
||||
|
||||
|
||||
if(!memcmp(current_atom,"\xA9" "nam",4)) { /* Song name */
|
||||
pmp3->title=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"aART",4)) {
|
||||
} else if(!memcmp(current_atom,"aART",4)) {
|
||||
pmp3->album_artist=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"\xA9" "ART",4)) {
|
||||
pmp3->artist=strdup((char*)¤t_data[16]);
|
||||
|
@ -253,7 +254,7 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
} else if(!memcmp(current_atom,"trkn",4)) {
|
||||
us_data=*((unsigned short *)¤t_data[18]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->track=us_data;
|
||||
|
||||
us_data=*((unsigned short *)¤t_data[20]);
|
||||
|
@ -263,27 +264,27 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
} else if(!memcmp(current_atom,"disk",4)) {
|
||||
us_data=*((unsigned short *)¤t_data[18]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->disc=us_data;
|
||||
|
||||
|
||||
us_data=*((unsigned short *)¤t_data[20]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->total_discs=us_data;
|
||||
} else if(!memcmp(current_atom,"\xA9" "day",4)) {
|
||||
pmp3->year=atoi((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"gnre",4)) {
|
||||
genre=(int)(*((char*)¤t_data[17]));
|
||||
genre--;
|
||||
|
||||
|
||||
if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
|
||||
genre=WINAMP_GENRE_UNKNOWN;
|
||||
|
||||
|
||||
pmp3->genre=strdup(scan_winamp_genre[genre]);
|
||||
} else if (!memcmp(current_atom, "cpil", 4)) {
|
||||
pmp3->compilation = current_data[16];
|
||||
}
|
||||
|
||||
|
||||
free(current_data);
|
||||
current_offset+=current_size;
|
||||
}
|
||||
|
@ -316,7 +317,7 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
|
||||
/* DWB: use ms time instead of sec */
|
||||
pmp3->song_length=(int)((samples * ms) / sample_size);
|
||||
DPRINTF(E_DBG,L_SCAN,"Song length: %d seconds\n",
|
||||
DPRINTF(E_DBG,L_SCAN,"Song length: %d seconds\n",
|
||||
pmp3->song_length / 1000);
|
||||
}
|
||||
|
||||
|
@ -324,7 +325,7 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
|
||||
/* see if it is aac or alac */
|
||||
atom_offset = scan_aac_drilltoatom(fin,
|
||||
"moov:trak:mdia:minf:stbl:stsd:alac",
|
||||
"moov:trak:mdia:minf:stbl:stsd:alac",
|
||||
&atom_length);
|
||||
|
||||
if(atom_offset != -1) {
|
||||
|
@ -336,10 +337,10 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
}
|
||||
|
||||
/* Get the sample rate from the 'mp4a' atom (timescale). This is also
|
||||
found in the 'mdhd' atom which is a bit closer but we need to
|
||||
found in the 'mdhd' atom which is a bit closer but we need to
|
||||
navigate to the 'mp4a' atom anyways to get to the 'esds' atom. */
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
"moov:trak:mdia:minf:stbl:stsd:mp4a",
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
"moov:trak:mdia:minf:stbl:stsd:mp4a",
|
||||
&atom_length);
|
||||
if(atom_offset == -1) {
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
|
@ -351,7 +352,7 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
fseek(fin, atom_offset + 32, SEEK_SET);
|
||||
|
||||
/* Timescale here seems to be 2 bytes here (the 2 bytes before it are
|
||||
* "reserved") though the timescale in the 'mdhd' atom is 4. Not sure
|
||||
* "reserved") though the timescale in the 'mdhd' atom is 4. Not sure
|
||||
* how this is dealt with when sample rate goes higher than 64K. */
|
||||
fread(buffer, sizeof(unsigned char), 2, fin);
|
||||
|
||||
|
@ -362,8 +363,8 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
|||
|
||||
/* Get the bit rate from the 'esds' atom. We are already positioned
|
||||
in the parent atom so just scan ahead. */
|
||||
atom_offset = scan_aac_findatom(fin,
|
||||
atom_length-(ftell(fin)-atom_offset),
|
||||
atom_offset = scan_aac_findatom(fin,
|
||||
atom_length-(ftell(fin)-atom_offset),
|
||||
"esds", &atom_length);
|
||||
|
||||
if (atom_offset != -1) {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
@ -97,12 +98,12 @@ int scan_aif_parse_comm(FILE *infile, MP3FILE *pmp3) {
|
|||
}
|
||||
|
||||
/* we'll brute the sample rate */
|
||||
|
||||
|
||||
pmp3->samplerate = aif_from_be32((uint32_t*)&comm.sample_rate[2]) >> 16;
|
||||
if(!pmp3->samplerate)
|
||||
return TRUE;
|
||||
|
||||
pmp3->bitrate = pmp3->samplerate * comm.channels *
|
||||
pmp3->bitrate = pmp3->samplerate * comm.channels *
|
||||
((comm.sample_size + 7)/8)*8;
|
||||
|
||||
sec = pmp3->file_size / (pmp3->bitrate / 8);
|
||||
|
@ -157,7 +158,7 @@ int scan_get_aifinfo(char *filename, MP3FILE *pmp3) {
|
|||
done=1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* fixup */
|
||||
chunk.len = aif_from_be32(&chunk.len);
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "restart.h"
|
||||
#include "daapd.h"
|
||||
#include "restart.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "scan-aac.h"
|
||||
|
@ -84,7 +85,7 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
atom_offset=scan_aac_drilltoatom(fin, "moov:udta:meta:ilst", &atom_length);
|
||||
if(atom_offset != -1) {
|
||||
/* found the tag section - need to walk through now */
|
||||
|
||||
|
||||
while(current_offset < (long) atom_length) {
|
||||
if(fread((void*)¤t_size,1,sizeof(int),fin) != sizeof(int))
|
||||
break;
|
||||
|
@ -92,13 +93,13 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
DPRINTF(E_SPAM,L_SCAN,"Current size: %d\n");
|
||||
|
||||
current_size=ntohl(current_size);
|
||||
|
||||
|
||||
if(current_size <= 7) /* something not right */
|
||||
break;
|
||||
|
||||
if(fread(current_atom,1,4,fin) != 4)
|
||||
if(fread(current_atom,1,4,fin) != 4)
|
||||
break;
|
||||
|
||||
|
||||
DPRINTF(E_SPAM,L_SCAN,"Current Atom: %c%c%c%c\n",
|
||||
current_atom[0],current_atom[1],current_atom[2],
|
||||
current_atom[3]);
|
||||
|
@ -110,13 +111,13 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
len=current_size-7; /* for ill-formed too-short tags */
|
||||
if(len < 22)
|
||||
len=22;
|
||||
|
||||
|
||||
current_data=(char*)malloc(len); /* extra byte */
|
||||
memset(current_data,0x00,len);
|
||||
|
||||
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
||||
|
||||
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
||||
break;
|
||||
|
||||
|
||||
if(!memcmp(current_atom,"\xA9" "nam",4)) { /* Song name */
|
||||
pmp3->title=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"\xA9" "ART",4)) {
|
||||
|
@ -139,7 +140,7 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
} else if(!memcmp(current_atom,"trkn",4)) {
|
||||
us_data=*((unsigned short *)¤t_data[18]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->track=us_data;
|
||||
|
||||
us_data=*((unsigned short *)¤t_data[20]);
|
||||
|
@ -149,27 +150,27 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
} else if(!memcmp(current_atom,"disk",4)) {
|
||||
us_data=*((unsigned short *)¤t_data[18]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->disc=us_data;
|
||||
|
||||
|
||||
us_data=*((unsigned short *)¤t_data[20]);
|
||||
us_data=ntohs(us_data);
|
||||
|
||||
|
||||
pmp3->total_discs=us_data;
|
||||
} else if(!memcmp(current_atom,"\xA9" "day",4)) {
|
||||
pmp3->year=atoi((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"gnre",4)) {
|
||||
genre=(int)(*((char*)¤t_data[17]));
|
||||
genre--;
|
||||
|
||||
|
||||
if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
|
||||
genre=WINAMP_GENRE_UNKNOWN;
|
||||
|
||||
|
||||
pmp3->genre=strdup(scan_winamp_genre[genre]);
|
||||
} else if (!memcmp(current_atom, "cpil", 4)) {
|
||||
pmp3->compilation = current_data[16];
|
||||
}
|
||||
|
||||
|
||||
free(current_data);
|
||||
current_offset+=current_size;
|
||||
}
|
||||
|
@ -202,17 +203,17 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
|
||||
/* DWB: use ms time instead of sec */
|
||||
pmp3->song_length=(int)((samples * ms) / sample_size);
|
||||
DPRINTF(E_DBG,L_SCAN,"Song length: %d seconds\n",
|
||||
DPRINTF(E_DBG,L_SCAN,"Song length: %d seconds\n",
|
||||
pmp3->song_length / 1000);
|
||||
}
|
||||
|
||||
pmp3->bitrate = 0;
|
||||
|
||||
/* Get the sample rate from the 'mp4a' atom (timescale). This is also
|
||||
found in the 'mdhd' atom which is a bit closer but we need to
|
||||
found in the 'mdhd' atom which is a bit closer but we need to
|
||||
navigate to the 'mp4a' atom anyways to get to the 'esds' atom. */
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
"moov:trak:mdia:minf:stbl:stsd:mp4a",
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
"moov:trak:mdia:minf:stbl:stsd:mp4a",
|
||||
&atom_length);
|
||||
if(atom_offset == -1) {
|
||||
atom_offset=scan_aac_drilltoatom(fin,
|
||||
|
@ -224,7 +225,7 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
fseek(fin, atom_offset + 32, SEEK_SET);
|
||||
|
||||
/* Timescale here seems to be 2 bytes here (the 2 bytes before it are
|
||||
* "reserved") though the timescale in the 'mdhd' atom is 4. Not sure
|
||||
* "reserved") though the timescale in the 'mdhd' atom is 4. Not sure
|
||||
* how this is dealt with when sample rate goes higher than 64K. */
|
||||
fread(buffer, sizeof(unsigned char), 2, fin);
|
||||
|
||||
|
@ -235,8 +236,8 @@ int scan_get_mp4info(char *filename, MP3FILE *pmp3) {
|
|||
|
||||
/* Get the bit rate from the 'esds' atom. We are already positioned
|
||||
in the parent atom so just scan ahead. */
|
||||
atom_offset = scan_aac_findatom(fin,
|
||||
atom_length-(ftell(fin)-atom_offset),
|
||||
atom_offset = scan_aac_findatom(fin,
|
||||
atom_length-(ftell(fin)-atom_offset),
|
||||
"esds", &atom_length);
|
||||
|
||||
if (atom_offset != -1) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <string.h>
|
||||
#include <taglib/tag_c.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "err.h"
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "restart.h"
|
||||
#include "err.h"
|
||||
|
|
|
@ -467,6 +467,12 @@ int scan_xml_playlist(char *filename) {
|
|||
}
|
||||
|
||||
rbdestroy(scan_xml_db);
|
||||
|
||||
MAYBEFREE(scan_xml_itunes_version);
|
||||
MAYBEFREE(scan_xml_itunes_base_path);
|
||||
MAYBEFREE(scan_xml_itunes_decoded_base_path);
|
||||
MAYBEFREE(scan_xml_real_base_path);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -956,6 +962,7 @@ int scan_xml_playlists_section(int action, char *info) {
|
|||
}
|
||||
dont_scan=0;
|
||||
state=XML_PL_ST_EXPECTING_PL_TRACKLIST;
|
||||
MAYBEFREE(current_name);
|
||||
return XML_STATE_PLAYLISTS;
|
||||
}
|
||||
if(action == RXML_EVT_BEGIN)
|
||||
|
@ -967,8 +974,7 @@ int scan_xml_playlists_section(int action, char *info) {
|
|||
if(action == RXML_EVT_TEXT) {
|
||||
/* got the value we were hoping for */
|
||||
if(next_value == XML_PL_NEXT_VALUE_NAME) {
|
||||
if(current_name)
|
||||
free(current_name);
|
||||
MAYBEFREE(current_name);
|
||||
current_name = strdup(info);
|
||||
DPRINTF(E_DBG,L_SCAN,"Found playlist: %s\n",current_name);
|
||||
/* disallow specific playlists */
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
|
||||
|
@ -47,7 +47,7 @@ extern int scan_get_mp3info(char *filename, MP3FILE *pmp3);
|
|||
extern int scan_get_urlinfo(char *filename, MP3FILE *pmp3);
|
||||
extern int scan_get_aifinfo(char *filename, MP3FILE *pmp3);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Typedefs
|
||||
*/
|
||||
typedef struct scannerlist_tag {
|
||||
|
@ -137,7 +137,7 @@ void usage(int errorcode) {
|
|||
fprintf(stderr,"options:\n\n");
|
||||
fprintf(stderr," -d level set debuglevel (9 is highest)\n");
|
||||
fprintf(stderr," -c config read config file\n");
|
||||
|
||||
|
||||
fprintf(stderr,"\n\n");
|
||||
exit(errorcode);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ int main(int argc, char *argv[]) {
|
|||
} else {
|
||||
av0 = argv[0];
|
||||
}
|
||||
|
||||
|
||||
while((option = getopt(argc, argv, "d:c:")) != -1) {
|
||||
switch(option) {
|
||||
case 'd':
|
||||
|
@ -167,13 +167,13 @@ int main(int argc, char *argv[]) {
|
|||
case 'c':
|
||||
configfile=optarg;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
fprintf(stderr,"Error: unknown option (%c)\n\n",option);
|
||||
usage(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "daapd.h"
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "os.h"
|
||||
#include "plugin.h"
|
||||
|
@ -23,7 +23,7 @@ void usage(void) {
|
|||
fprintf(stderr," -f file file to transcode\n");
|
||||
fprintf(stderr," -p plugin plugin to use\n");
|
||||
fprintf(stderr," -t codectype\n");
|
||||
|
||||
|
||||
fprintf(stderr,"\n\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
36
src/uici.c
36
src/uici.c
|
@ -4,14 +4,14 @@
|
|||
*
|
||||
* ** NOTICE **
|
||||
*
|
||||
* This code is written by (and is therefore copyright) Dr Kay Robbins
|
||||
* (krobbins@cs.utsa.edu) and Dr. Steve Robbins (srobbins@cs.utsa.edu),
|
||||
* and was released with unspecified licensing as part of their book
|
||||
* This code is written by (and is therefore copyright) Dr Kay Robbins
|
||||
* (krobbins@cs.utsa.edu) and Dr. Steve Robbins (srobbins@cs.utsa.edu),
|
||||
* and was released with unspecified licensing as part of their book
|
||||
* _UNIX_Systems_Programming_ (Prentice Hall, ISBN: 0130424110).
|
||||
*
|
||||
* Dr. Steve Robbins was kind enough to allow me to re-license this
|
||||
* software as GPL. I would request that any bugs or problems with
|
||||
* this code be brought to my attention (ron@pedde.com), and I will
|
||||
* Dr. Steve Robbins was kind enough to allow me to re-license this
|
||||
* software as GPL. I would request that any bugs or problems with
|
||||
* this code be brought to my attention (ron@pedde.com), and I will
|
||||
* submit appropriate patches upstream, should the problem be with
|
||||
* the original code.
|
||||
*
|
||||
|
@ -42,6 +42,8 @@
|
|||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "uici.h"
|
||||
|
||||
#ifndef MAXBACKLOG
|
||||
|
@ -69,7 +71,7 @@ static int u_ignore_sigpipe() {
|
|||
act.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,30 +85,30 @@ static int u_ignore_sigpipe() {
|
|||
* -1 on error and sets errno
|
||||
*/
|
||||
int u_open(u_port_t port) {
|
||||
int error;
|
||||
int error;
|
||||
struct sockaddr_in server;
|
||||
int sock;
|
||||
int true = 1;
|
||||
|
||||
if ((u_ignore_sigpipe() == -1) ||
|
||||
((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&true,
|
||||
sizeof(true)) == -1) {
|
||||
error = errno;
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
server.sin_port = htons((short)port);
|
||||
if ((bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1) ||
|
||||
(listen(sock, MAXBACKLOG) == -1)) {
|
||||
error = errno;
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
@ -142,10 +144,10 @@ int u_accept(int fd, struct in_addr *hostaddr) {
|
|||
while (((retval =
|
||||
accept(fd, (struct sockaddr *)(&netclient), &len)) == -1) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
;
|
||||
if (retval == -1)
|
||||
return retval;
|
||||
|
||||
|
||||
*hostaddr = netclient.sin_addr;
|
||||
return retval;
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ int u_connect(u_port_t port, char *hostn) {
|
|||
struct hostent *phe;
|
||||
|
||||
|
||||
/* fix broken name resolution for hosts beginning with a
|
||||
/* fix broken name resolution for hosts beginning with a
|
||||
* digit, plus get rid of hostname lookup stuff
|
||||
*/
|
||||
if(inet_addr(hostn) == INADDR_NONE) {
|
||||
|
@ -201,11 +203,11 @@ int u_connect(u_port_t port, char *hostn) {
|
|||
(errno == EINTR) ) {
|
||||
FD_ZERO(&sockset);
|
||||
FD_SET(sock, &sockset);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retval == -1) {
|
||||
error = errno;
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
while ((close(sock) == -1) && (errno == EINTR));
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ int _util_initialized=0;
|
|||
|
||||
/* Forwards */
|
||||
//int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size_t slen, char *from, char *to);
|
||||
void _util_hexdump(unsigned char *block, int len);
|
||||
void _util_mutex_init(void);
|
||||
|
||||
/**
|
||||
|
@ -399,7 +398,7 @@ int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size
|
|||
}
|
||||
*/
|
||||
|
||||
void _util_hexdump(unsigned char *block, int len) {
|
||||
void util_hexdump(unsigned char *block, int len) {
|
||||
char charmap[256];
|
||||
int index;
|
||||
int row, offset;
|
||||
|
@ -429,7 +428,7 @@ void _util_hexdump(unsigned char *block, int len) {
|
|||
strcat(output,tmp);
|
||||
}
|
||||
|
||||
fprintf(stderr,"%s\n",output);
|
||||
DPRINTF(E_LOG,L_MISC,"%s\n",output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef enum {
|
|||
l_err,
|
||||
l_conf,
|
||||
l_plugin,
|
||||
l_memdebug,
|
||||
l_last
|
||||
} lock_t;
|
||||
|
||||
|
@ -46,6 +47,7 @@ extern int util_utf8toutf16(unsigned char *utf16, int dlen, unsigned char *utf8,
|
|||
extern int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, int len);
|
||||
extern int util_utf16_byte_len(unsigned char *utf16);
|
||||
|
||||
extern void util_hexdump(unsigned char *block, int len);
|
||||
|
||||
|
||||
#endif /* _UTIL_H_ */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "messages.h"
|
||||
|
||||
static HANDLE elog_handle = NULL;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
char *av0;
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
/* need better longopt detection in configure.in */
|
||||
struct option longopts[] =
|
||||
{ { "help", 0, NULL, 'h' },
|
||||
|
@ -130,7 +130,7 @@ size_t parse_hdr(unsigned char *hdr, size_t hdr_len,
|
|||
sample_rate = GET_WAV_INT32(hdr + 24);
|
||||
sample_bit_length = GET_WAV_INT16(hdr + 34);
|
||||
data_length = GET_WAV_INT32(hdr + 20 + format_data_length + 4);
|
||||
|
||||
|
||||
if ((format_data_length != 16) ||
|
||||
(compression_code != 1) ||
|
||||
(channel_count < 1) ||
|
||||
|
@ -271,11 +271,11 @@ int main(int argc, char **argv)
|
|||
while ((c = getopt(argc, argv, "hl:o:s:")) != -1) {
|
||||
#endif
|
||||
switch(c) {
|
||||
case 'h':
|
||||
case 'h':
|
||||
usage(0);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
|
||||
case 'l':
|
||||
sec = strtoul(optarg, &end, 10);
|
||||
if ((optarg[0] == '-') || (end == optarg) || ((end[0] != '\0') && (end[0] != '.'))) {
|
||||
|
@ -284,7 +284,7 @@ int main(int argc, char **argv)
|
|||
} else if (*end == '.') {
|
||||
char tmp[7];
|
||||
int i;
|
||||
|
||||
|
||||
memset(tmp, '0', sizeof (tmp) - 1);
|
||||
tmp[sizeof (tmp) - 1] = '\0';
|
||||
for (i = 0; (i < (sizeof (tmp) - 1)) && (isdigit(end[i+1])); i++)
|
||||
|
@ -306,7 +306,7 @@ int main(int argc, char **argv)
|
|||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 's':
|
||||
samples = strtoul(optarg, &end, 10);
|
||||
if ((optarg[0] == '-') || (end == optarg) || (end[0] != '\0')) {
|
||||
|
@ -322,7 +322,7 @@ int main(int argc, char **argv)
|
|||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'o':
|
||||
offset = strtoul(optarg, &end, 10);
|
||||
if ((*optarg == '-') || (end == optarg) || (*end != '\0')) {
|
||||
|
@ -330,13 +330,13 @@ int main(int argc, char **argv)
|
|||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: Bad command line option -%c.\n", av0, optopt);
|
||||
usage(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
|
@ -373,7 +373,7 @@ int main(int argc, char **argv)
|
|||
memmove(hdr, hdr + offset, hdr_len - offset);
|
||||
hdr_len -= offset;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
offset -= hdr_len;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "restart.h"
|
||||
#include "webserver.h"
|
||||
|
|
|
@ -29,10 +29,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
|
||||
#include "configfile.h"
|
||||
#include "conf.h"
|
||||
#include "db-generic.h"
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "os.h"
|
||||
|
|
Loading…
Reference in New Issue