nap-1.5.4.orig/0000777000175000017500000000000010523245653011063 5ustar dzdznap-1.5.4.orig/INSTALL0000744000175000017500000000004707574256550012124 0ustar dzdz#! /bin/sh ./configure && make install nap-1.5.4.orig/config.h.in0000644000175000017500000000457410523147674013120 0ustar dzdz/* config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the `assume_default_colors' function. */ #undef HAVE_ASSUME_DEFAULT_COLORS /* Define to 1 if you have the `hstrerror' function. */ #undef HAVE_HSTRERROR /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `ncurses' library (-lncurses). */ #undef HAVE_LIBNCURSES /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NCURSES_H /* Define if socklen_t is defined in sys/socket.h. */ #undef HAVE_SOCKLEN_T /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strsep' function. */ #undef HAVE_STRSEP /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION nap-1.5.4.orig/mkinstalldirs0000744000175000017500000000133307235362335013666 0ustar dzdz#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.2 2001/01/29 21:47:09 selinger Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here nap-1.5.4.orig/missing0000774000175000017500000002466610523013116012460 0ustar dzdz#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2003-09-02.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: nap-1.5.4.orig/Makefile.in0000664000175000017500000004346610523245624013141 0ustar dzdz# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ depcomp install-sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = depcomp = am__depfiles_maybe = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_OBJS = @EXTRA_OBJS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ SUBDIRS = src doc EXTRA_DIST = COPYRIGHT README.win README.ncurses all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps'; \ cd $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu --ignore-deps Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkdir_p) $(distdir)/doc @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-recursive ctags \ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \ dist-tarZ dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-recursive distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive \ mostlyclean mostlyclean-generic mostlyclean-recursive pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nap-1.5.4.orig/aclocal.m40000664000175000017500000007546210523147463012737 0ustar dzdz# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR nap-1.5.4.orig/configure.in0000644000175000017500000000226310523147260013366 0ustar dzdzdnl Process this file with autoconf to produce a configure script. AC_INIT(src/nap.c) AM_INIT_AUTOMAKE(nap, 1.5.4) DATE="November 2006" AM_CONFIG_HEADER(config.h) dnl Check for programs. AC_PROG_CC AC_PROG_INSTALL dnl Check for libraries. AC_CHECK_LIB(socket, gethostbyname) AC_CHECK_LIB(dl, dlopen) AC_CHECK_LIB(ncurses, initscr) if test "$ac_cv_lib_ncurses_initscr" != yes; then AC_MSG_ERROR(ncurses not found. See README.ncurses) fi AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(resolv, inet_aton) AC_CHECK_LIB(nsl, connect) dnl Check for header files. AC_HEADER_STDC AC_CHECK_HEADERS(ncurses.h) dnl Check for library functions AC_CHECK_FUNCS(memcpy) AC_CHECK_FUNCS(hstrerror) AC_CHECK_FUNCS(assume_default_colors) AC_CHECK_FUNCS(vasprintf) AC_CHECK_FUNCS(strcasestr) AC_CHECK_FUNCS(strsep) dnl Check for size of types [not currently used] dnl AC_CHECK_SIZEOF(int, 4) dnl Check for socklen_t in sys/socket.h AC_MSG_CHECKING([for socklen_t]) AC_TRY_COMPILE( #include , socklen_t s, AC_DEFINE(HAVE_SOCKLEN_T, 1, Define if socklen_t is defined in sys/socket.h.) AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(EXTRA_OBJS) AC_OUTPUT([Makefile src/Makefile doc/Makefile doc/nap.1]) nap-1.5.4.orig/README0000644000175000017500000001620507575035401011744 0ustar dzdz******************** Linux Napster Client ******************** Written by Kevin Sullivan. See COPYRIGHT. Modified by Peter Selinger and others. See ChangeLog and AUTHORS. INSTALLATION: To compile nap from sources, first do "./configure", followed by "make". This will create the files "nap" and "napping". If you downloaded a binary distribution for your platform, you do not need to compile anything. RUNNING: The first time you run nap, it will prompt you for some information and save this information to a configuration file for you. It will also build your "library", or a list of the files that you are sharing. The next time you start nap, it will only prompt you for missing information, and it will automatically update your library if it is out of date. If you get an error relating to the ncurses library, you will either have to upgrade your current version or install it. *Command Line Options* -h, --help - print this help message -v, --version - print version info and exit -b, --build - build library of shared files to send to server -B, --build-only - build library and exit -N, --nobuild - do not build library, even if it is out of date -m, --create - create new account on server (obsolete) -r, --reconnect - keep reconnecting until server connection established -a, --autorestart - automatically reconnect when connection to server lost -q, --daemon - run without user interface; file sharing only -t, --notitle - do not display title bar (fixes messed-up displays) -l, --nxterm - try using a terminal which is compatible with most systems (fixes some messed-up displays) -T, --transparent - use terminal's default background instead of black -n, --noserver - start up without connecting to a server -f, --config fn - config file to use (default $HOME/.nap/napconf) -x, --log fn - log all transfers to a specific filename -g, --logall fn - log everything to a specific filename -s, --server sv:port - select a specific server (multiple -s opts possible) -d, --debug n - set debug level -u, --user str - specify napster username -p, --pass str - specify user's password -e, --email str - specify user's email address -U, --upload dir - specify upload directory (multiple -U opts possible) -D, --download dir - specify download directory -I, --incomplete dir - specify directory for incomplete files -P, --dataport n-m - specify port(s) to use for incoming upload requests -C, --connection n - specify connection speed number (see README) -M, --maxuploads n - specify maximum number of simultaneous uploads -o, --option var=value - set user variable CONNECTION SPEED CHART (-C option): Connection | Number ------------------- Unknown | 0 14.4 | 1 28.8 | 2 33.6 | 3 56.7 | 4 64K ISDN | 5 128K ISDN | 6 Cable | 7 DSL | 8 T1 | 9 T3 or > | 10 IN CLIENT: Assuming you are familiar with ircii or BitchX or another UNIX IRC client, you should have no trouble figuring out this client. Here is a partial list of commands. For a full, up-to-date list, try /help, or see userguide.html. *Regular Commands* /help - Returns help on the specified command. /join [chan] - Joins channel "chan". /part [chan] - Parts channel/query "chan", or if the 2nd argument is omitted, the current channel/query. /quit - Exits the client. /tquit - Leaves the client running and exits it when all transfers have finished. /disconnect - Disconnects you from the server. /reconnect - Reconnects you to the server. /tell - Sends a private message. /msg - An alias for /tell. /me - Performs an action with the message specified. /whois - Returns information on the user you specify. /finger - An alias for /whois. /g - Attempt to get the file numbers which are returned with /search. (ex. /g 60-63,31,75) /search - Performs a search for a file matching "string". *Note* For ping times to be returned with /search, root privileges are required. /browse - Browses a user's files. /pup - Prints out a list of your current uploads. /dup - Deletes the upload number "number" retrieved from /pup (Only works if transfer hasn't started.) /pdown - Prints out a list of your current downloads. /ddown - Deletes the download number "number" retrieved from /pdown. /dns - Attempts to resolve a hostname or IP. /clear - Clears your screen buffer. /ping - Pings another user. /clist - Returns a listing of the current channels, the number of users and the current topic. /clist2 - The same as /clist except that it returns user created channels as well. /names [channel] - Returns the current userlist of your current channel or the channel you specify (you must be on the channel). /window - Allows you to open every channel/query in a seperate window, which can be cycled through with Ctrl-X. /query - Starts a private message conversation between you and "user". Queries act like channels. /about - Returns some information about the client and "thank you"s. /ignore [user] - Attempts to ignore a user. /unignore - Attempts to unignore a user. *Aliases* /alias - Attempts to create an alias with the name specified. Special Alias Variables: $1 - Replaces all occurences of $1 in "alias" with the first argument given. $2 - Replaces all occurences of $2 in "alias" with the second argument given. ... $1- - Replaces all occurences of $1- in "alias" with the first argument as well as all following arguments. $2- - Replaces all occurences of $2- in "alias" with the second argument as well as all following arguments. ... /unalias - Attempts to unalias the alias "name". /aliaslist - Returns a list of all created aliases. /loadalias - Attempts to load aliases from "filename". *Note* A file with the name ".nap_aliases" is automatically loaded everytime the client is started. /savealias - Attempts to save aliases to "filename". *Navigation* Page Up/Meta-V - Scrolls the screen up 10 lines. Page Down/Ctrl-V - Scrolls the screen down 10 lines. Meta-Backspace/Meta-Delete - deletes the token before the cursor End - Returns to the bottom of the screen. Ctrl-X - Switches between current channels. Ctrl-L - Refresh the screen. Ctrl-B - Toggles bold (only compatible with this client as far as I know). Ctrl-T - Scrolls the topic. Ctrl-A/Ctrl-E - go the beginning/end of line Ctrl-D - delete character at cursor Ctrl-K - delete rest of line Tab - Attempts to autocomplete a command or username. ESC Char is equivalent to Meta-Char. COMMENTS: If you discover a bug, or have a question, comment or suggestion, please report them to the maintainer. The current maintainer is Peter Selinger, selinger@users.sourceforge.net. The newest version is at http://nap.sourceforge.net/. ORIGINAL AUTHOR: Kevin Sullivan Ignitor http://www.gis.net/~nite/ nite@gis.net nap-1.5.4.orig/src/0000777000175000017500000000000010523245654011653 5ustar dzdznap-1.5.4.orig/src/scheck.c0000644000175000017500000003053007575445607013271 0ustar dzdz/* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ #include #include #include #include #include #include #include #include #include #include #include "defines.h" #include "codes.h" #include "colors.h" #include "scheck.h" #include "timer.h" #include "nap.h" #include "winio.h" #include "lists.h" #ifdef MEMWATCH #include "memwatch.h" #endif extern info_t info; extern int srch; extern int reconnect; /* the global connection list */ sock_t *socklist = NULL; /* bandwidth observers for global uploads and global downloads */ bandwidth_t bwup, bwdown; /* set by /quit to cause an immediate unconditional shutdown of nap, or by qevent() after a /tquit */ int quit_now = 0; /* add a connection to end of global connection list. s is file descriptor, nm is name, t is type (S_R or S_W), func is handler function. d is left blank. nm is copied (strdup). Returns the new socklist element. Also, if this is an upload or download connection, notify server (ugly!) */ /* Note that upload/dowload notification is done in event.c:dosend() and event.c:doget() for connections initiated by a remote client. */ sock_t *addsock(int s, char *nm, unsigned char t, int (*func)(WINDOW *, sock_t *)) { sock_t *cur, *sv; /* create a new socket */ cur = (sock_t *)malloc(sizeof(sock_t)); cur->fd = s; cur->t = t; cur->socknm = strdup(nm); cur->func = func; cur->next = NULL; cur->dxx = NULL; cur->shared_to_send = NULL; cur->utask = NULL; cur->dtask = NULL; cur->btask = NULL; cur->bwlimit = 0; /* an add it to the list */ list_append(sock_t, socklist, cur); /* if it's an upload or a download, notify the server */ sv = findsock("server"); if (sv) { if (cur->socknm[0] == 'u' && cur->socknm[1] == ' ') { sendpack(sv->fd, NAP_UP, NULL); } else if (cur->socknm[0] == 'd' && cur->socknm[1] == ' ') { sendpack(sv->fd, NAP_DOWN, NULL); } } return cur; } /* delete a connection. It is uniquely identified by its file descriptor s. This routine also notifies the server if an upload or download is being shut down (this is ugly, since this should rather be done in connection with the task structure, not the connection structure). It also sets srch to 0 in case we are deleting the server connection. It also shuts down the socket of the connection, and closes it, if it is indeed a socket connection (file descriptor >2). */ void delsock(int s) { sock_t *cur, *sv; library_t *l; /* unlink the first connection whose fd is s, if any */ list_unlink_cond(sock_t, socklist, cur, cur->fd == s); if (!cur) { return; } sv = findsock("server"); if (sv) { if (cur->socknm[0] == 'd' && cur->socknm[1] == ' ') { sendpack(sv->fd, NAP_DOWNDONE, NULL); } else if (cur->socknm[0] == 'u' && cur->socknm[1] == ' ') { sendpack(sv->fd, NAP_UPDONE, NULL); } } if (!strcmp(cur->socknm, "server")) srch = 0; if (cur->shared_to_send) { list_forall_unlink(l, cur->shared_to_send) { free(l->lfn); free(l->hash); free(l); } } free(cur->socknm); free(cur); /* Note: a connection handler may not close the socket before or * after the call to delsock(), since it is always closed here, and * it can be harmful (segfault) to close a file twice. */ if (s > 2) { shutdown(s, 2); close(s); } return; } /* finds a connection by name in the connection list */ sock_t *findsock(const char *nm) { sock_t *elt; list_find(elt, socklist, !strcasecmp(elt->socknm, nm)); return(elt); } /* finds a connection by file descriptor in the connection list */ sock_t *findsockfd(int fd) { sock_t *elt; list_find(elt, socklist, elt->fd == fd); return(elt); } /* prints the list of connections to the specified window. */ void psocks(WINDOW *win) { sock_t *cur; wp(win, "fd | nm\n"); for (cur=socklist;cur!=NULL;cur=cur->next) wp(win, "%2d %s\n", cur->fd, cur->socknm); drw(win); } /* the next few functions are for bandwidth limiting. The idea is that a bandwidth "observer" is created for each bandwidth limit. Every time bytes travel through the connection, the observer is informed. The observer calculates, on demand, the number of microseconds one has to wait until the next packet may be sent/received. */ /* register n bytes that have been sent and are subject to bw */ void bandwidth_register(bandwidth_t *bw, int n) { bw->bytes += n; } /* initialize bw */ void bandwidth_init(bandwidth_t *bw) { bw->bandwidth = 0; } /* return the time in microseconds that this connection has to sleep in order to satisfy its bandwidth constraint. curbw is the bandwidth currently requested by the user; note that this may be different from bw->bandwidth if the requested bandwidth changed, or the very first time this is called for a connection. tp is a pointer to a timeval structure that holds the current time. */ long bandwidth_waittime(bandwidth_t *bw, int curbw, struct timeval *tp) { long ms; if (curbw < 0) curbw = 0; /* First check if the requested bandwidth differs from the stored one. If yes, re-calculate state. */ if (bw->bandwidth != curbw) { if (bw->bandwidth == 0) { bw->bandwidth = curbw; bw->time0 = tp->tv_sec; bw->bytes = tp->tv_usec / 1000 * curbw; } else { bw->bytes = (bw->bytes / bw->bandwidth) * curbw; bw->bandwidth = curbw; } } if (curbw==0) return 0; /* no bandwidth limit requested */ /* next, adjust the time0 parameter to tp->tv_sec, i.e., to the integer component of the current time. */ if (tp->tv_sec != bw->time0) { bw->bytes -= curbw * 1000 * (tp->tv_sec - bw->time0); bw->time0 = tp->tv_sec; } /* calculate the number of microseconds this connection needs to sleep */ ms = bw->bytes / curbw * 1000 - tp->tv_usec; /* if we are more than a second behind, forfeit anything beyond one second of credit. I.e., normally we get credit for being "too slow" (and can make up for it later), but at most one second's worth of such credit is allowed */ if (ms < -1000000) { bw->bytes = (tp->tv_usec / 1000 - 1000) * curbw; ms = bw->bytes / curbw * 1000 - tp->tv_usec; } return ms; } /* sockfunc: this is the main event loop of the nap program. It is * here that we wait for network activity and then tend to the various * different connections (including user input). In addition, we call * tevent() (in timer.c) once a second or so, to take care of * scheduled events. * * This function is called precisely once, from nap.c:main(). Once * we leave here, nap shuts down and terminates. * * up is the input window (equal to the global variable winput), and * win is the output window of the terminal interface (equal to the * global variable wchan). Why not just refer to the global variables, * as do some of the procedures that are called from here? * * The connection handlers (cur->func) are always supposed to return 1 * (the return value is not currently checked). If a connection * handler wants to shut down, it needs to call delsock(). * **/ void sockfunc(WINDOW *win, WINDOW *up) { fd_set fs, fw; /* sets of file descriptors to watch, see "man select" */ int r; sock_t *cur; struct timeval sec; /* note originally used timespec here instead of timeval - this was a type error */ long timeout, msup, msdown; struct timeval tv; library_t *lib; bandwidth_init(&bwup); bandwidth_init(&bwdown); while (1) { dochecks(); /* notify terminal that it has been resized, if necessary. */ drw(up); /* redraw input window to position cursor */ /* if the --autorestart option is set, and there is no server, try to reconnect to a server. */ if (info.autorestart == 1) { for (cur=socklist;cur!=NULL;cur=cur->next) { if (!strcasecmp(cur->socknm, "server")) break; } if (cur==NULL) { sleep(1); /* sleep to avoid excessive load in case of infinite loop */ wp(win, "Connection to server lost, reconnecting...\n"); drw(win); dreconnect(-1, "reconnect", NULL, 0, win); } } /* we return if this was requested by the /quit command or by /tquit in conjunction with qevent() */ if (quit_now) { goto quit; } /* we reconnect if this was requested by a SIGUSR1 signal */ if (reconnect) { reconnect = 0; dreconnect(-1, "reconnect", NULL, 0, win); } /* determine current time */ gettimeofday(&tv, NULL); msup = bandwidth_waittime(&bwup, info.bandwidthup, &tv); msdown = bandwidth_waittime(&bwdown, info.bandwidthdown, &tv); timeout = 1000000; /* let select() time out after at most this many microsecs */ /* let fs be the set of "read" file descriptors, and fw the list of "write" file descriptors, from the connection list */ FD_ZERO(&fs); FD_ZERO(&fw); for (cur=socklist;cur!=NULL;cur=cur->next) { if (cur->bwlimit) { /* bandwidth limiting code */ int ms; /* calculate the sleep time for this connection */ if (cur->t == S_R) { ms = bandwidth_waittime(&cur->bw, info.bandwidthdownconn, &tv); if (msdown > ms) { ms = msdown; } } else { ms = bandwidth_waittime(&cur->bw, info.bandwidthupconn, &tv); if (msup > ms) { ms = msup; } } /* if ms<=0, activity is immediately allowed and we proceed to watch this connection in the "select" call below. Else if ms>0, activity is not allowed, but we make sure "select" will time out after ms microseconds so that this connection can be added at that time. */ if (ms>0) { if (timeout > ms) { timeout = ms; } continue; } } if (cur->t == S_R) FD_SET(cur->fd, &fs); else if (cur->t == S_W) FD_SET(cur->fd, &fw); /* special case: the server is normally polled for reading, but if we have stuff scheduled to send to it, we poll for writing as well */ if (strcmp(cur->socknm, "server")==0 && cur->shared_to_send) { FD_SET(cur->fd, &fw); } } /* prepare timeout, then wait for activity on connections. On fs connections, wait for characters to be available for reading. On fw connections, wait for ability to write. */ sec.tv_sec = timeout / 1000000; sec.tv_usec = timeout % 1000000; r = select(FD_SETSIZE, &fs, &fw, NULL, &sec); /* timeout guarantees calling the following at least once per second */ tevent(); /* check for timer events */ qevent(); /* check queues */ /* if there is an error, print it, but then continue. However, EINTR means select was interrupted. This happens e.g. when the user resizes the window. */ if (r == -1) { if (errno != EINTR) { wp(win, ""RED"* Error while watching connections: %s"WHITE"\n", \ strerror(errno)); drw(win); } continue; } /* if there was no network activity, continue main loop */ if (r == 0) continue; /* else do something for every connection that had activity. Essentially, just call the handler (cur->func) for that connection. */ for (cur=socklist;cur!=NULL;cur=cur->next) { if (cur->t == S_R && FD_ISSET(cur->fd, &fs)) { FD_CLR(cur->fd, &fs); cur->func(win, cur); if (quit_now) { goto quit; } cur=socklist; /* need to start from beginning since sockets might have been deleted in the meantime */ } else if (cur->t == S_W && FD_ISSET(cur->fd, &fw)) { FD_CLR(cur->fd, &fw); cur->func(win, cur); if (quit_now) { goto quit; } cur=socklist; } else if (strcmp(cur->socknm, "server")==0 && cur->shared_to_send && FD_ISSET(cur->fd, &fw)) { FD_CLR(cur->fd, &fw); /* send scheduled stuff to server */ /* unlink first element */ lib = cur->shared_to_send; cur->shared_to_send = lib->next; r = sendpack(cur->fd, NAP_SFILE, "\"%s\" %s %i %i %i %i", lib->lfn, lib->hash, lib->sz, lib->bitrate, lib->freq, lib->len); free(lib->lfn); free(lib->hash); free(lib); cur=socklist; /* not strictly necessary, but just in case... */ } } } /* end of loop not reachable */ quit: /* we get here if the user issues the /quit command. */ while (socklist!=NULL) delsock(socklist->fd); return; } nap-1.5.4.orig/src/defines.h0000644000175000017500000000610510523146607013435 0ustar dzdz#ifndef _NAP_DEFINES_H #define _NAP_DEFINES_H /* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ #define USE_COLORS #include "config.h" #ifdef __CYGWIN32__ #define setbuffer(s, b, t) setvbuf(s, b, b ? _IOFBF : _IONBF, t) #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) /* make up for an apparent bug in cygwin ncurses implementation */ #undef ACS_VLINE #undef ACS_HLINE #define ACS_VLINE '|' #define ACS_HLINE '-' #endif #ifndef HAVE_SOCKLEN_T #define socklen_t int #endif typedef int (*ucmd_func_t)(); /* some static limits */ #define MAXCHANS 5 #define BACKLOG 32 #define LINEINDENT " " #define SCROLLSIZE 10000 /* incomplete files of this size or less are considered "turds" and will be removed. This is the default value; the actual value can be overridden by the turdsize user variable. */ #define TURDSIZE 100000 /* the default port for napster servers */ #define DEFAULT_PORT 8888 /* where to get news about new versions of this client */ #define NEWSURL "http://nap.sourceforge.net/UPDATE" #define NEWSTIMEOUT 5 /* default for the "connecttimeout" variable */ #define CONNECTTIMEOUT 5 /* where to get information about servers, napigator-style */ /* By default, one of METASERVER_1 and METASERVER_2 is picked "round-robin". */ #define METASERVER_1 "http://www.gotnap.com/servers.txt" #define METASERVER_2 "http://www.gotnap.com/servers.txt" #define METATIMEOUT 5 /* the client name which we send to the server on login. This can now be overridden by the "identity" user variable, as certain OpenNap servers have been known to be nasty to nap ("bad client"). */ #define IDENTITY "nap v" VERSION /* name of the "napping" application to use for pings. */ #define NAPPING "napping" /* some file names for standard files. These filenames are relative to the user's home directory, unless noted otherwise. */ #define CONFIGDIR ".nap" #define CONFIGFILE CONFIGDIR "/napconf" #define LIBRARYFILE CONFIGDIR "/shared" #define HOTLISTFILE CONFIGDIR "/hotlist-%s" /* %s is user name */ #define ALIASFILE CONFIGDIR "/aliases" #define HANDLERFILE CONFIGDIR "/handlers" #define CHANNELFILE CONFIGDIR "/channels-%s" /* %s is user name */ #define OLDNEWSFILE CONFIGDIR "/oldnews" #define GLOBALCONFIGFILE "/etc/naprc" /* library file header, must change when the file format changes */ #define NAP_LIBRARY_HEADER \ "NAP LIBRARY FILE v02. Automatically generated file, do not edit." /* markers that are used to add checksum tags to incomplete files */ #define INCTAG_START "" /* bogus hash value to use if real hashing is turned off. Note: this must be 32 characters long */ #define BOGUS_HASH "00000000000000000000000000000000" #define newwin(n, l, c, y, x) (newwin(l, c, y, x)) /* some generic macros */ #define NAP_MAX(x,y) ((x) > (y) ? (x) : (y)) #define NAP_MIN(x,y) ((x) < (y) ? (x) : (y)) #endif /* _NAP_DEFINES_H */ nap-1.5.4.orig/src/mp3s.c0000644000175000017500000004661307574516716012723 0ustar dzdz/* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ /* the main functions in this file are mp3info and ogginfo. They extract information such as file size, bitrate, sample frequency, and md5 hash from a named file */ #include #include #include #include #include #include #include #include "alias.h" #include "md5.h" #include "mp3s.h" #include "defines.h" #ifdef MEMWATCH #include "memwatch.h" #endif /* arrays are indexed using id & bitrate fields from frame header */ /* 1st row is for MPEG-2 (id=0) Layer III, 2nd for MPEG-1 (id=1) Layer III */ int bratetab[2][16] = { { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 }, { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 } }; int freqtab[2][4] = { { 22050, 24000, 16000, 50000 }, /* MPEG-2 */ { 44100, 48000, 32000, 50000 } /* MPEG-1 */ }; /* check for valid mp3 header. Return 1 if ok. */ int checkhdr(hdr_t *h) { if (h->sync != 0xfff || h->layer != 1 || h->brate == 15 || h->freq == 3 || h->emph == 2) return(0); return(1); } /* get "real" header info from an mp3 file. The stream f is already positioned to skip any id3v2 header, if present */ int getrhdr(int f, hdr_t *r) { unsigned char bw[4]; int n; n = read(f, bw, sizeof(bw)); if (n < 4) { /* e.g. near EOF */ return(0); } buf4tohdr(bw, r); if (!checkhdr(r)) { return(0); } return(1); } /* convert an array of four bytes into a frame header (hdr_t) structure */ void buf4tohdr(unsigned char *bw, hdr_t *r) { /* Note: to ensure portability, use explicit assignments and shift operators, rather than writing binary data directly into the hdr_t structure. The difference in efficiency is negligible. -PS */ r->emph = (bw[3] & 0x03) >> 0; r->original = (bw[3] & 0x04) >> 2; r->copyright = (bw[3] & 0x08) >> 3; r->mode_ext = (bw[3] & 0x30) >> 4; r->mode = (bw[3] & 0xc0) >> 6; r->pvt = (bw[2] & 0x01) >> 0; r->pad = (bw[2] & 0x02) >> 1; r->freq = (bw[2] & 0x0c) >> 2; r->brate = (bw[2] & 0xf0) >> 4; r->prot = (bw[1] & 0x01) >> 0; r->layer = (bw[1] & 0x06) >> 1; r->id = (bw[1] & 0x08) >> 3; r->sync = (bw[1] & 0xf0) >> 4; r->sync |= (bw[0] & 0xff) << 4; } /* bitmasks for Xing flags */ #define XING_FRAMES 0x0001 #define XING_BYTES 0x0002 #define XING_TOC 0x0004 #define XING_VBR_SCALE 0x0008 /* check if the frame with header h at startpos is an Xing VBR info frame * if yes, return 1 and calculate the length of the bitstream in seconds and * the average bitrate. * The Xing VBR info frame is "documented" in LAME's VbrTag.[ch] files. * It looks like a normal mp3 frame (it starts with a valid frame header) * but instead of containing bitstream data, it contains information on the * VBR bitsteam. It can be identified by the string "Xing" immediately * following the frame's side info. The next four bytes give flags identifying * what information is available in the frame. Usually, the info frame * provides the number of frames, the number of bytes in the bitstream * (excluding ID3 tags etc.), a 100-byte table of contents (TOC) array to * help an mp3 player seek within a VBR file, and a "VBR scale". We only care * about the first two items. */ int checkxing(int f, hdr_t h, int startpos, size_t sz1, int *seconds, int *avgbrate) { unsigned char buf[16]; unsigned char *p; int bpsi, n, spf; unsigned long flags, numframes, numbytes; /* determine number of bytes of side info + optional 16-bit CRC */ if (h.id == 1) bpsi = (h.mode == 3) ? 17 : 32; else bpsi = (h.mode == 3) ? 9 : 17; if (h.prot == 0) /* 16-bit CRC follows frame header */ bpsi += 2; /* skip header, CRC, and side info */ lseek(f, startpos+4+bpsi, SEEK_SET); n = read(f, buf, sizeof(buf)); if (n < 16) { return 0; } if (strncmp(buf, "Xing", 4) != 0) { return 0; } /* this frame is an Xing info frame; next four bytes are the Xing flags */ p = buf+4; flags = (unsigned long)p[0] << 24 | (unsigned long)p[1] << 16 | \ (unsigned long)p[2] << 8 | (unsigned long)p[3]; if (flags & XING_FRAMES) { /* next four bytes give number of frames */ p = buf+8; numframes = (unsigned long)p[0] << 24 | (unsigned long)p[1] << 16 | \ (unsigned long)p[2] << 8 | (unsigned long)p[3]; } else { /* Xing frame doesn't even tell us how many frames there are! */ return 0; } if (flags & XING_BYTES) { /* next 4 bytes give number of bytes in bitstream */ p = buf+12; numbytes = (unsigned long)p[0] << 24 | (unsigned long)p[1] << 16 | \ (unsigned long)p[2] << 8 | (unsigned long)p[3]; } else { /* just use what we already know about the bitstream size */ numbytes = sz1; } if ((numframes == 0) || (numbytes == 0)) { /* broken Xing frame? */ return 0; } /* number of seconds = numframes * (seconds per frame) * seconds per frame = (samples/frame)*(seconds/sample) = spf * (1/freq) * spf = 1152 (MPEG-1 Layer III) or 576 (MPEG-2 Layer III) (576*2=1152) */ spf = (h.id) ? 1152 : 576; *seconds = numframes * spf / freqtab[h.id][h.freq]; *avgbrate = numbytes * 8 / (*seconds * 1000); return 1; } /* check if two frame headers have same id, layer, prot, freq, mode fields */ int samestream(hdr_t a, hdr_t b) { if ((a.id == b.id) && (a.layer == b.layer) && (a.prot == b.prot) && (a.freq == b.freq) && (a.mode == b.mode)) { return(1); } return(0); } /* The frame length is calculated as follows: * bpf = bytes per frame (including frame header) * = bits/second * bytes/bit * samples/frame * seconds/sample * = 1000 * kbps * 1/8 * spf * (1/freq) * = kbps * 125 * spf * (1/freq) * spf = 1152 (MPEG-1 Layer III) or 576 (MPEG-2 Layer III) * * Note that freq doesn't evenly divide into kbps*spf*125 when freq is * 22050 or 44100. It seems that encoders deal with the remainder by adding * an extra byte to some of the frames and setting the pad bit in the frame * header. We must add one to bpf if a frame header's pad bit is 1. */ int framesize(hdr_t h) { int kbps, freq, bpf, spf; kbps = bratetab[h.id][h.brate]; freq = freqtab[h.id][h.freq]; spf = (h.id) ? 1152 : 576; bpf = (kbps * spf * 125 / freq) + h.pad; return(bpf); } /* return 1 if it looks like the file has a variable bitrate * startpos is the position in file f where the mp3 stream starts, * size is the size of f in bytes * If there is no Xing VBR info frame, * the only way to know for sure if a file is VBR is to read every single * frame header. This takes a relatively long time, so we use an approximate * method borrowed from Cedric Tefft's mp3info. The idea is to sample a few * frame headers throughout the file to see if they have the same bitrate as * the first header in the file. Although this works well in practice, * it is not fail-proof: * 1) some VBR files might not be recognized as VBR if the set of * headers sampled happen to have the same bitrate * 2) because we jump into the middle of the file and look for a frame header, * it is possible that what looks like a frame header is actually frame * data. If this false frame header happens to have a bitrate field that * differs from that of the first header, a non-VBR file might be * incorrectly identified as VBR. As a result, the file will be unneccessarily * fully scanned in mp3info. */ int checkvbr(int f, int startpos, int size, hdr_t firsthdr) { int stepsize, i, j, isvbr, headerfound, bpf; unsigned char buf[4]; hdr_t h, h2; isvbr = 0; stepsize = (size - startpos)/4; /* sample up to three headers throughout the file and compare the * header's bitrate to that of the first header */ for (i = 1; i < 4; i++) { lseek(f, startpos + i*stepsize, SEEK_SET); headerfound = 0; /* get first four bytes at this position */ if (read(f, buf, 4) < 4) break; /* scan for frame header. Limit search to max frame size (1440 bytes) */ for (j = 0; j < 1440; j++) { buf4tohdr(buf, &h); if (checkhdr(&h) && samestream(firsthdr, h)) { /* id, layer, prot, freq, and mode match first header */ /* if h is really a header, there should also be a header following * this frame */ bpf = framesize(h); lseek(f, bpf-4, SEEK_CUR); if (read(f, buf, 4) < 4) break; buf4tohdr(buf, &h2); if (checkhdr(&h2) && samestream(firsthdr, h2)) { /* found two consecutive frame headers that match first header's * id, layer, prot, freq, and mode. h is probably a real header. */ headerfound = 1; break; } /* h2 is not a valid header, so neither is h. Rewind. */ lseek(f, -bpf, SEEK_CUR); } /* h is not a valid header; continue searching */ buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = buf[3]; if (!read(f, &buf[3], 1)) break; } /* end for j */ if (!headerfound) { /* there's something wrong (couldn't find a valid header) * but we pretend not to notice (act as if the file were CBR) */ break; } if (firsthdr.brate != h.brate) { /* bitrates differ */ isvbr = 1; break; } /* bitrates matched, try a header in another section of the file */ } /* end for */ return(isvbr); } /* get the mp3 information (bitrate, frequency, length in seconds, size in bytes, and checksum) from the named mp3 file. */ mhdr_t *mp3info(char *fn) { hdr_t m; mhdr_t *r; int f; size_t size = 0; struct stat st; id3v2_t tag; char rdt[3]; size_t id3size, endtagsize; int numframes, bpf, spf; int seconds, avgbrate; hdr_t h; int res; f = open(fn, O_RDONLY); if (f == -1) return(NULL); /* first check whether there is an id3v2 header. Let id3size be its length. */ id3size = 0; memset(rdt, 0, sizeof(rdt)); read(f, &rdt, 3); if (!strncmp(rdt, "ID3", 3)) /* found id3v2 header */ { lseek(f, 0, SEEK_SET); read(f, &tag, sizeof(tag)); /* corrected a bug here: according to id3v2 spec, the size is * represented as a "synchsafe", or base-128, integer. * This means 28 bits encode 32 bits as follows: * 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx means * 0000xxxx xxxxxxxx xxxxxxxx xxxxxxxx. -PS */ size = (long)tag.size[0] << (24-3)|(long)tag.size[1] << (16-2)|(long)tag.size[2] << (8-1)|(long)tag.size[3]; /* skip the id3v2 header */ if (tag.flags & 0x10) { /* this is new in id3v2 version 4.0: tag.flags & 0x10 indicates the presence of a "footer", which is 10 bytes in length, and which is *not* included in the stored tag size */ id3size = size+20; } else { id3size = size+10; } } /* next, check for the existence of a 128-byte tag at the end of the file. Let endtagsize be its length. */ endtagsize = 0; lseek(f, -128, SEEK_END); memset(rdt, 0, sizeof(rdt)); read(f, &rdt, 3); if (!strncmp(rdt, "TAG", 3)) /* found end-tag */ endtagsize = 128; /* first mp3 header should begin just after ID3 tag */ lseek(f, id3size, SEEK_SET); if (!getrhdr(f, &m)) { close(f); return(NULL); } fstat(f, &st); r = (mhdr_t *)malloc(sizeof(mhdr_t)); memset(r, 0, sizeof(mhdr_t)); /* sample frequency and size. Note: r->sz is the file size, whereas r->sz1 is the length of the mp3 stream (=file size minus any tags) */ r->freq = freqtab[m.id][m.freq]; r->sz = st.st_size; r->sz1 = r->sz - id3size - endtagsize; /* to set the song length and average bitrate, we must do different things depending on whether the file is VBR (variable bitrate) or not. */ /* check if first frame is an Xing VBR info frame */ if (checkxing(f, m, id3size, r->sz1, &seconds, &avgbrate)) { r->len = seconds; r->bitrate = avgbrate; } else if (checkvbr(f, id3size, st.st_size, m)) { /* Count the number of frames to determine the length in seconds. * number of seconds = numframes * (seconds per frame) * seconds per frame = (samples/frame)*(seconds/sample) = spf * (1/freq) * (seconds/frame is independent of bitrate) * spf = 1152 (MPEG-1 Layer III) or 576 (MPEG-2 Layer III) (576*2=1152) * (samples/frame is independent of bitrate and frequency) * We have to read all the frame headers to determine the number of frames * because each frame can have a different bitrate and therefore a different * length. * * avg bitrate = (sum of bitrates over all frames)/numframes */ lseek(f, id3size, SEEK_SET); numframes = 0; while (getrhdr(f, &h)) { /* at this point we know m.brate < 15, m.freq < 3, and m.layer = 1 * all frames should have same frequency, layer, and id but we don't * check for this */ numframes++; bpf = framesize(h); lseek(f, bpf-4, SEEK_CUR); /* seek to next frame header */ } /* end while getrhdr */ /* at this point we have reached EOF or an invalid header */ if (numframes == 0) { /* no valid headers found */ close(f); free(r); return(NULL); } spf = (m.id) ? 1152 : 576; r->len = numframes * spf / r->freq; /* avg bitrate in kbps = (number of kilobits)/(number of seconds) */ if (r->len == 0) { /* patch #442669, jpavel */ /* We have a problem here. */ close(f); free(r); return(NULL); } r->bitrate = (r->sz1/r->len)/125; } else { /* assume bitrate is constant */ r->bitrate = bratetab[m.id][m.brate]; r->len = (r->sz1/r->bitrate)/125; } /* finally, seek to end of ID3 header and calculate md5 hash */ lseek(f, id3size, SEEK_SET); res = md5hash(r->check, f); if (res) { free(r); close(f); return(NULL); } close(f); return(r); } /* support for ogg vorbis files: get standard information (bitrate, frequency, length in seconds, size in bytes, and checksum) from the names ogg vorbis file. Return NULL if not recognized as a valid ogg vorbis file. */ mhdr_t *ogginfo(char *fn) { /* note: since ogg uses variable bitrate, to keep things simple, we use the "nominal", rather than the "actual" bitrate of the ogg stream. This information can be read from the first header packet. Otherwise we'd have to scan the entire file. We also only give a rough estimate of the song length, based on the file size. Sorry. Scanning an ogg vorbis file for that information would require ogg and vorbis parsers, which is too much overhead for us here. */ /* we make some simple assumptions: the file contains an ogg stream revision 0, whose first page contains precisely one package, which is a vorbis "1" header. All other kinds of ogg streams will fail here. Information on ogg streams comes from http://www.xiph.org/ogg/vorbis/doc/framing.html, information on vorbis "1" header comes from vorbis/lib/info.c in the vorbis distribution. */ unsigned char buf[0x58]; int n; int f; mhdr_t *r; struct stat st; int res; /* get file stats and read first 58 bytes */ f = open(fn, O_RDONLY); if (f == -1) { return NULL;goto fail; } fstat(f, &st); n = read(f, buf, 58); if (n<58) { goto fail; } /* check that this is a first page of a logical ogg stream. We don't bother checking the CRC checksum */ if (strncmp(&buf[0], "OggS", 4) != 0) { /* capture pattern */ goto fail; } if (buf[4] != 0) { /* stream structure version */ goto fail; } if ((buf[5] & 3) != 2) { /* ogg header type flag */ goto fail; } if (buf[18] || buf[19] || buf[20] || buf[21]) {/* page sequence no. */ goto fail; } if (buf[26] != 1 || buf[27] != 30) { /* segment table */ goto fail; } /* check that this is a vorbis "1" header */ if (buf[28] != 1) { /* vorbis packet type */ goto fail; } if (strncmp(&buf[29], "vorbis", 6) != 0) { /* vorbis packet identifier */ goto fail; } if (buf[35] || buf[36] || buf[37] || buf[38]) {/* vorbis version */ goto fail; } if ((buf[57] & 1) != 1) { /* EOP check */ goto fail; } /* seems we found an okay vorbis packet, now read the data. We ignore the "upper" and "lower" bitrates and go straight for the nominal bitrate. */ r = (mhdr_t *)malloc(sizeof(mhdr_t)); if (!r) { goto fail; /* out of memory; fail silently */ } /* channels = buf[39]; */ r->freq = buf[40] | (buf[41]<<8) | (buf[42]<<16) | (buf[43]<<24); r->bitrate = buf[48] | (buf[49]<<8) | (buf[50]<<16) | (buf[51]<<24); r->sz = st.st_size; r->sz1 = st.st_size; /* we have to estimate the length, based on bitrate and file size */ if(!r->bitrate) { /* bitrate was for some reason zero */ free(r); goto fail; } r->len = r->sz * 8 / r->bitrate; /* convert from bps to kbps */ r->bitrate /= 1000; /* calculate checksum */ lseek(f, 0, SEEK_SET); res = md5hash(r->check, f); if (res) { free(r); goto fail; } close(f); return r; fail: close(f); return NULL; } /* calculate md5 hash of the given stream, starting from the current file position. md5bocks is the number of blocks to hash. Write to check. Return -1 on error, else 0. New in 1.5.1: if the user variable "hash" is not set, do not hash, but return a constant string instead. */ int md5hash(char check[33], int fd) { unsigned char md5[16]; int i; if (nvar_default("hash", 0) == 0) { /* do not hash - return constant string */ strcpy(check, BOGUS_HASH); return 0; } /* We hash the first 300032 bytes, not 300000 bytes as nap used to do. By the way, 300032 = 1024 * 293. -PS */ if (md5_stream_blocks(fd, 293, md5)) { return(-1); } for (i=0;i<16;i++) sprintf(check+2*i, "%02x", md5[i]); /* check[32] = '\0'; */ return(0); } /* the next function really belongs in md5.c, but since that file is taken verbatim from GNU, we prefer not to change it. */ /* Compute MD5 message digest for 1024 * KB bytes read from file FD. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. Return 1 on error. */ int md5_stream_blocks (int fd, int kb, void *resblock) { struct md5_ctx ctx; char buffer[1024 + 72]; size_t sum; /* Initialize the computation context. */ md5_init_ctx (&ctx); /* Iterate over full file contents. */ while (kb>0) { /* We read the file in blocks of 1024 bytes. One call of the computation function processes the whole buffer so that with the next round of the loop another block can be read. */ size_t n; sum = 0; /* Read block. Take care for partial reads. */ do { n = read (fd, buffer + sum, 1024 - sum); sum += n; } while (sum < 1024 && n != 0 && n != -1); if (n == -1) return 1; /* If end of file is reached, end the loop. */ if (n == 0) { /* Add the last bytes if necessary. */ if (sum > 0) md5_process_bytes (buffer, sum, &ctx); break; } /* Process buffer with 1024 bytes. Note that 1024 % 64 == 0 */ md5_process_block (buffer, 1024, &ctx); kb--; } /* Construct result in desired memory. */ md5_finish_ctx (&ctx, resblock); return 0; } nap-1.5.4.orig/src/status_line.c0000644000175000017500000001470107777577244014374 0ustar dzdz/* This file was contributed by Suzanne Skinner and is copyrighted under the GNU General Public License. (C) 2002 Suzanne Skinner. The code contained in this file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "dynstr.h" #include "getline.h" #include "defines.h" /* for NAP_MIN(), NAP_MAX() */ #include "nap.h" #include "winio.h" #include "dlul_screen.h" #include "colors.h" #include "status_line.h" /*** Private Function Prototypes ***/ static void sl_scroll_left(void); static void sl_scroll_right(void); static void sl_scroll_to(int); static dynstr sl_text = NULL; static dynstr sl_input_text = NULL; static int sl_scroll_pos = 0; static bool sl_input_mode_on = FALSE; static int sl_input_cursor = 0; static const char *sl_input_mode_prefix = "/search "; /* Set the text of the status line to "str". Note: input-mode keeps a separate * buffer which will not be effected by sl_set or sl_sprintf. This function * has the side effect of setting sl_scroll_pos to 0, unless str is identical * to the original status-line text or input-mode is on. */ void sl_set(const char *str) { if (!sl_input_mode_on && strcmp(ds_get(&sl_text), str) != 0) sl_scroll_pos = 0; ds_set(&sl_text, str); sl_draw(); } /* sprintf text into the status line (there is no length limit). Note: * input-mode keeps a separate buffer which will not be effected by sl_set or * sl_sprintf. This function has the side effect of setting sl_scroll_pos to 0 * (unless input-mode is on). */ void sl_sprintf(const char *format, ...) { va_list args; va_start(args, format); ds_vsprintf(&sl_text, format, args); va_end(args); if (!sl_input_mode_on) { sl_scroll_pos = 0; sl_draw(); } } /* Draws the status line to the bottom line of the current window (determined * by checking the "screen" global variable). This function is called by any * sl_ function that changes the contents (or scroll-state) of the status line, * and may also be called externally as needed (e.g. after a screen switch). * * The status line will be displayed in white-on-red, unless input-mode is * active, in which case it is displayed in inverse video. * * Note: sl_draw will never call wrefresh, nor will any sl_ function. * Screen refreshing is left to the higher level. */ void sl_draw(void) { WINDOW *win; int attrib; const char *text; switch (screen) { case RESULT_SCREEN: win = swin; break; case DLUL_SCREEN: win = dlul_win; break; default: return; } if (sl_input_mode_on) { attrib = A_REVERSE; text = ds_get(&sl_input_text); } else { attrib = COLOR_PAIR(CPWR); text = ds_get(&sl_text); } wattron(win, attrib); wmove(win, LINES-1, 0); whline(win, ' ', COLS); waddnstr(win, text + sl_scroll_pos, NAP_MIN(COLS, strlen(text + sl_scroll_pos))); if (sl_input_mode_on) wmove(win, LINES-1, sl_input_cursor - sl_scroll_pos); wattroff(win, attrib); } /* Call this function any time a keystroke is received on a screen that uses * status_line.c. It will return TRUE if the keystroke applied to the * status line (left/right scrolling, input mode, etc.), in which case no * further handling should be done. If it returns FALSE, the keystroke was not * of interest and should be handled by the caller instead. * * If input-mode is active and the user types ENTER after entering a search * command, the command will be executed via cmds.c:parseout(). Input mode is * then exited and the scroll position is set back to 0. * * Note: This function will grab *all* keystrokes if input-mode is on. */ bool sl_handle_keystroke(chtype ch) { sock_t *sock_data; int sock; if (sl_input_mode_on) { sl_input_cursor = gl_handle_keystroke(&sl_input_text, strlen(sl_input_mode_prefix), sl_input_cursor, ch); if (sl_input_cursor == GL_DONE) { sl_input_mode_on = FALSE; sl_scroll_pos = sl_input_cursor = 0; sl_set(""); if (ds_len(&sl_input_text) > strlen(sl_input_mode_prefix)) { sock_data = findsock("server"); sock = (sock_data ? sock_data->fd : -1); parseout(sock, ds_get(&sl_input_text), wchan); } } else if (sl_input_cursor == GL_ABORT) { sl_input_mode_on = FALSE; sl_scroll_pos = sl_input_cursor = 0; sl_set("Input aborted."); } else { sl_scroll_to(sl_input_cursor); } sl_draw(); return TRUE; } switch (ch) { case KEY_LEFT: sl_scroll_left(); sl_draw(); return TRUE; case KEY_RIGHT: sl_scroll_right(); sl_draw(); return TRUE; case ' ': sl_input_mode_on = TRUE; ds_set(&sl_input_text, sl_input_mode_prefix); sl_scroll_pos = 0; sl_input_cursor = ds_len(&sl_input_text); sl_draw(); return TRUE; } return FALSE; } /*** Private ***/ static void sl_scroll_left(void) { sl_scroll_pos -= NAP_MAX(COLS/2, 1); if (sl_scroll_pos < 0) sl_scroll_pos = 0; } static void sl_scroll_right(void) { int len; len = ds_len(sl_input_mode_on ? &sl_input_text : &sl_text); if (sl_scroll_pos + COLS > len) return; sl_scroll_pos += NAP_MAX(COLS/2, 1); if (sl_scroll_pos > len) sl_scroll_pos = len; } /* scoll so that cursor is visible. For a very long line, this "while" implementation is slower than an equivalent "modulo" calculation, but conceptually simpler. */ static void sl_scroll_to(int cursor) { while (cursor < sl_scroll_pos) { sl_scroll_left(); } while (cursor >= sl_scroll_pos + COLS) { sl_scroll_right(); } } nap-1.5.4.orig/src/timer.h0000644000175000017500000000153507574256557013164 0ustar dzdz#ifndef _NAP_TIMER_H #define _NAP_TIMER_H /* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ struct timer_s { time_t t; time_t interval; /* "new" timer: arbitrary callback function */ void (*callback)(void *data); /* callback function */ void *data; /* callback data (allocated) */ char *desc; /* a description printed by tlist (alloc'd) */ bool recurring; /* is it a repeating event? */ struct timer_s *next; }; typedef struct timer_s ntimer_t; void tevent(void); void timerlist(WINDOW *); void pfunc(ntimer_t *); ntimer_t *addtimer(int sec, void callback(void *data), void *data, char *desc, bool recurring); void deltimer(ntimer_t *); bool deltimer_by_index(int index); #endif /* _NAP_TIMER_H */ nap-1.5.4.orig/src/winio.c0000644000175000017500000010563107575445607013163 0ustar dzdz/* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ /* this file contains procedures related to the main window: drawing, redrawing, scrolling, user input, etc. */ #ifdef HAVE_CONFIG_H # include #endif #define _GNU_SOURCE /* needed for stdio.h:vasprintf */ #include #include #include #include #include #include #include #include #include #include "defines.h" #include "codes.h" #include "nap.h" #include "colors.h" #include "winio.h" #include "alias.h" #include "irc.h" #include "lists.h" #include "scheck.h" #include "sscr.h" #include "dlul_screen.h" #include "missing.h" #ifdef MEMWATCH #include "memwatch.h" #endif extern info_t info; extern int ircmode, wmode; extern chans_t *curchan; /* current channel, if any */ extern upload_t *up; /* download task list */ extern download_t *down; /* download task list */ extern scount_t scount; /* libraries, songs, gigs */ extern char *mnick; extern int noprint; extern int ircsock; extern alias_t *alhead; /* alias list */ extern out_nap_cmd_t out[]; /* list of builtin commands */ extern WINDOW *swin; /* the new model for managing input screens is as follows: */ /* the number of the currently active screen. Currently three values are possible: MAIN_SCREEN, RESULT_SCREEN, and DLUL_SCREEN. However, further screens may be added in the future (such as: resume screen, configuration screen) */ int screen; /* Each screen has its own curses windows, and its own global state (such as: scroll buffer, command history, and input state for main screen, search item under cursor, displayed information categories, etc, for search screen). When switching screens, it is equally important to switch the input focus. In the new model, there is only one "input" connection which remains active at all times, but its "func" component is set to a different handler for different screens. Its "d" component is not used. It is imperative to update the "screen" variable and this handler at the same time, or else the user input will be directed to an invisible screen. */ /* individual screens may choose to delete their curses windows when they are not switched on (the search result screen does this), or to retain them (the main screen does it this way). */ /* each screen should provide a procedure for switching it on (initializing its state, windows, and input handler) and for switching it off (deleting any part of the state that is not needed). The function switchscreen(n) switches to screen number n, setting "screen" as appropriate, and calling the individual screen's off and on routines. */ /* curses windows and global state for main screen */ WINDOW *wchan=NULL, *winput, *sep, *whead; int tind = 0; /* indentation of the title (channel topic) */ chans_t *recent = NULL; /* most recent channel; (always NULL) */ scroll_t *mscroll = NULL; /* top of the main scroll */ scroll_t *mscrollend = NULL; /* bottom of the main scroll */ scroll_t *scur = NULL; /* last line now displayed, or NULL for end */ int mscrollsize = 0; /* length of the main scroll */ int lastlogflag = 0; /* set to 1 during output of "lastlog" command - this causes these lines to be marked and ignored in future "lastlog" commands. */ /* the command history */ cmds_t *cmdl, *cmdlend = NULL; /* A doubly linked list of lines, possibly empty. This is read-only, except that new lines can be appended at the end, and the total length of the list is bounded by BACKLOG. */ int cmdlsize = 0; /* length of the command history */ cmds_t *ccmd = NULL; /* a pointer to the line in cmdl which the current edit is based on, or NULL if the current edit is from scratch */ unsigned char cbuf[512]; /* the line currently being edited */ unsigned char cscratch[512]; /* a place where the current "from scratch" line is saved if ccmd != NULL */ int curr = 0; /* first char of cbuf displayed on screen */ int curx = 0; /* cursor position in cbuf */ /* global state for search screen is defined in sscr.c */ colortab_t colortab[] = { { RED, CPR, 1 }, { GREEN, CPG, 1 }, { WHITE, CPW, 1 }, { BLUE, CPB, 1 }, { YELLOW, CPY, 1 }, { MAGENTA, CPM, 1 }, { CYAN, CPC, 1, }, { BOLD, A_BOLD, 0 }, { DARK, A_DIM, 0 }, { BLINK, A_BLINK, 0 }, { UNDERLINE, A_UNDERLINE, 0 }, { NULL, -1, 0 } }; /* switch to screen number n (which should be MAIN_SCREEN, RESULT_SCREEN, or DLUL_SCREEN). Returns 0 if we already were on that screen (without redrawing it), 1 if there was a real switch, and -1 on error. */ int switchtoscreen(int n) { if (n==screen) { return 0; } /* check that screen selected is valid */ switch (n) { case MAIN_SCREEN: case RESULT_SCREEN: case DLUL_SCREEN: break; default: return(-1); } /* turn off old screen */ switch (screen) { case MAIN_SCREEN: /* nothing to do */ break; case RESULT_SCREEN: endsearchscr(); break; case DLUL_SCREEN: enddlulscr(); break; default: return(-1); break; } screen = n; /* turn on new screen */ switch (n) { case MAIN_SCREEN: mainscr(); break; case RESULT_SCREEN: searchscr(); break; case DLUL_SCREEN: dlulscr(); break; default: /* not reachable */ return(-1); break; } return(1); } /* switch to the next available screen */ int nextscreen(void) { switch(screen) { case MAIN_SCREEN: switchtoscreen(RESULT_SCREEN); break; case RESULT_SCREEN: switchtoscreen(DLUL_SCREEN); break; case DLUL_SCREEN: default: switchtoscreen(MAIN_SCREEN); break; } return(1); } /* switch to main screen */ void mainscr(void) { sock_t *sk; sk = findsock("input"); if (sk) { sk->func = input; } dscr(wchan); drw(wchan); dstatus(); indraw(); } void resize() { sock_t *t; struct winsize ws; memset(&ws, 0, sizeof(ws)); ioctl(fileno(stdin), TIOCGWINSZ, &ws); resizeterm(ws.ws_row, ws.ws_col); winput->_begy = LINES-1; winput->_begx = 0; sep->_begy = LINES-2; sep->_begx = 0; if (info.notop) wresize(wchan, LINES-2, COLS); else wresize(wchan, LINES-3, COLS); wresize(winput, 1, COLS); if (!info.notop) wresize(whead, 1, COLS); wresize(sep, 1, COLS); drw(wchan); drw(sep); dstatus(); /* redraw input screen */ werase(winput); t = findsock("input"); if (t) { indraw(); } dscr(wchan); drw(wchan); drw(winput); if (screen==RESULT_SCREEN) { plist(); } else if (screen == DLUL_SCREEN) { dlul_refresh(); } return; } void wstats(WINDOW *win) { wp(win, "stdscr to %i - %i\n", stdscr->_maxy, stdscr->_maxx); wp(win, "winput to %i - %i\n", winput->_maxy, winput->_maxx); wp(win, "sep to %i - %i\n", sep->_maxy, sep->_maxx); wp(win, "wchan to %i - %i\n", wchan->_maxy, wchan->_maxx); wp(win, "LINES/COLS to %i - %i\n", LINES, COLS); drw(win); } void drw(WINDOW *win) { if (info.daemon || !win) return; if (screen==RESULT_SCREEN && win == swin) wrefresh(win); else if (screen==DLUL_SCREEN && win == dlul_win) wrefresh(win); else if (screen==MAIN_SCREEN) wrefresh(win); } void dstatus() { int j, lg; char *t = NULL; user_t *cur; int nu, nd, ndq; download_t *dtask; upload_t *utask; list_count(down, nd, dtask, ACTIVE(dtask->state) && dtask->state!=RRQUEUED); list_count(down, ndq, dtask, dtask->state == QUEUED || dtask->state == RQUEUED || dtask->state == RRQUEUED); list_count(up, nu, utask, !STOPPED(utask->state)); if (info.daemon) { return; } werase(sep); if (!info.notop) werase(whead); for (j=0;jq || curchan->q == 1))) { msprintf(&t, "[U/%i D/%i Q/%i]", nu, nd, ndq); mvwprintw(sep, 0, COLS-(strlen(t)+1), t); free(t); mvwprintw(sep, 0, 0, cloaked ? " (%s)" : " [%s]", info.user); wprintw(sep, scount.songs == 1 ? " [%lu song" : " [%lu songs", scount.songs); wprintw(sep, scount.libraries == 1 ? " in %lu library" : " in %lu libraries", scount.libraries); wprintw(sep, scount.gigs == 1 ? " (%lu gig)]" : " (%lu gigs)]", scount.gigs); } else { if (!curchan || !curchan->users) mvwprintw(sep, 0, 0, " [%s]", mnick); else if (curchan->flag) { t = strdup(curchan->nm); if (strlen(curchan->nm) > COLS/4) t[COLS/4] = 0; cur = finduser(curchan, mnick); if (cur->flag & NAP_OP) mvwprintw(sep, 0, 0, " [@%s] [%s +", mnick, t); else if (cur->flag & NAP_VOICE) mvwprintw(sep, 0, 0, " [+%s] [%s +", mnick, t); else mvwprintw(sep, 0, 0, " [%s] [%s +", mnick, t); if (curchan->flag & NAP_I) waddch(sep, 'i'); if (curchan->flag & NAP_S) waddch(sep, 's'); if (curchan->flag & NAP_P) waddch(sep, 'p'); if (curchan->flag & NAP_T) waddch(sep, 't'); if (curchan->flag & NAP_M) waddch(sep, 'm'); if (curchan->flag & NAP_N) waddch(sep, 'n'); if (curchan->flag & NAP_K) waddch(sep, 'k'); if (curchan->flag & NAP_L) waddch(sep, 'l'); if (curchan->flag & NAP_K || curchan->flag & NAP_L) waddch(sep, ' '); if (curchan->flag & NAP_K) wprintw(sep, "%s", curchan->key); if (curchan->flag & NAP_K && curchan->flag & NAP_L) waddch(sep, ' '); if (curchan->flag & NAP_L) wprintw(sep, "%i", (unsigned int)curchan->l); waddch(sep, ']'); free(t); t = NULL; } else { t = strdup(curchan->nm); if (strlen(curchan->nm) > COLS/4) t[COLS/4] = 0; cur = finduser(curchan, mnick); if (cur->flag & NAP_OP) mvwprintw(sep, 0, 0, " [@%s] [%s]", mnick, t); else if (cur->flag & NAP_VOICE) mvwprintw(sep, 0, 0, " [+%s] [%s]", mnick, t); else mvwprintw(sep, 0, 0, " [%s] [%s]", mnick, t); free(t); t = NULL; } } if (!info.notop) { lg = COLS-(strlen(VERSION)+8)-4; if (lg >= 0) { mvwprintw(whead, 0, COLS-(strlen(VERSION)+8), "[nap v%s]", VERSION); if (curchan && curchan->q != 1 && curchan->topic) { t = (char *)malloc(lg+1); memset(t, 0, lg+1); if (strlen(curchan->topic) < lg + tind) { /* drw(wchan); */ /* why here? */ tind = strlen(curchan->topic)-lg; } if (tind < 0) tind = 0; if (tind + lg < strlen(curchan->topic)) { strncpy(t, curchan->topic+tind, lg-3); mvwprintw(whead, 0, 0, " [%s...]", t); } else { strncpy(t, curchan->topic+tind, lg); mvwprintw(whead, 0, 0, " [%s]", t); } free(t); } else if (curchan && curchan->q == 1) mvwprintw(whead, 0, 0, " [Query (%s)]", curchan->nm); if (screen == MAIN_SCREEN) wnoutrefresh(whead); } } if (screen == MAIN_SCREEN) { wnoutrefresh(sep); doupdate(); } } /* add the string STR to the given LOGFILE. If RP is set, replace escape sequences */ void addlog(char *logfile, char *str, int rp) { FILE *f; int i, k; static int bol = 1; /* are we at the beginning of a line? */ time_t ct; struct tm *r; /* note: some extra care is taken to print the date and time just before a line is printed, and not just after one is printed, although that would have been easier. */ ct = time(NULL); r = localtime(&ct); f = fopen(logfile, "a"); if (!f) { return; } if (!rp) { fputs(str, f); return; } for (i=0;str[i];i++) { if (bol) { fprintf(f, "[%02i/%02i %i:%02i] ", r->tm_mon+1, r->tm_mday, r->tm_hour, r->tm_min); bol = 0; } if (str[i] == '\e') { for (k=0; str[i] && str[i]!='m' && k<6; k++, i++) ; continue; } fputc(str[i], f); if (str[i] == '\n') { bol = 1; } } fclose(f); } int wp(WINDOW *win, const char *fmt, ...) { va_list args; char *str; int i; if (noprint == 2) return(0); str = NULL; va_start(args, fmt); vasprintf(&str, fmt, args); va_end(args); if (info.logallfile) addlog(info.logallfile, str, 1); if (win && !info.daemon) { addscroll(win, str); if (nvar_default("noscroll", 0)==0) { scur = NULL; /* be sure to scroll to bottom on output */ } dscr(win); } if (!win && info.daemon!=2) { printf("%s", str); fflush(stdout); /* flushing here helps OpenBSD, which will otherwise not flush automatically before reading password. -PS */ } i = strlen(str); free(str); return(i); } /* examines string s for escape sequences and returns a (statically allocated) string which represents the escape sequences (color, boldface) in effect at the end of string s. If end!=NULL, s is considered to end there. */ char *esc_getcolor(char *s, char *end) { static char out[11] = BOLD; char *col = out+strlen(BOLD); int bf=0; while (*s!=0 && (end==NULL || s=0 implies mscrollend != NULL */ static int len = -1; static int size, asize; /* real size and allocated size of current line, if len != -1. */ /* process each character or espace sequence from buf */ for (p=buf; *p!=0; p++) { if (*p == '\r') { /* ignore - concession to MSDOS? */ continue; } /* create a new logical line if there is no current line (previous character was '\n'). */ if (len==-1) { /* create a new empty line */ cur = (scroll_t *)malloc(sizeof(scroll_t)); cur->lastlog = lastlogflag; cur->chan = recent; cur->own = NULL; asize = 256; cur->line = (char *)malloc(asize); cur->line[0] = 0; /* attach to scroll */ dlist_append(mscroll, mscrollend, cur); mscrollsize++; /* initialize local state for appending to this line */ len = 0; size = 0; } cur = mscrollend; /* make sure at least 5 more characters fit in current line */ if (size+5+1 > asize) { asize += 256; cur->line = (char *)realloc(cur->line, asize); } if (*p == '\n') { /* mark this line ended - next printable character will start a new (logical and physical) line */ q = esc_getcolor(cur->line, NULL); if (q[0] != 0) { strcat(cur->line, WHITE); size += strlen(WHITE); } len = -1; /* free some memory by allocating a fixed size for this line */ q = strdup(cur->line); free(cur->line); cur->line = q; continue; } else if (*p == '\e') { /* escape sequence - copy to current line without counting its length towards the total */ if (p[3] == 'm') { strncat(cur->line, p, 4); size += 4; p += 3; } else { strncat(cur->line, p, 5); size += 5; p += 4; } continue; } else { /* printable character - copy it to current line */ if (*p!=' ' && len >= COLS-1) { /* the character will not fit. Find a good place to break line */ linebreak = strrchr(cur->line, ' '); if (linebreak - cur->line < COLS/2 || linebreak - cur->line < 40) { linebreak = NULL; } if (linebreak) { linebreak1 = linebreak + 1; while (linebreak > cur->line && linebreak[-1]==' ') { linebreak--; } } /* create continuation line */ new = (scroll_t *)malloc(sizeof(scroll_t)); new->lastlog = lastlogflag; new->chan = recent; new->own = cur->own ? cur->own : cur; asize = 256; new->line = (char *)malloc(asize); new->line[0] = 0; /* copy over stuff from old line to new one */ q = esc_getcolor(cur->line, linebreak); strcat(new->line, q); strcat(new->line, LINEINDENT); if (linebreak) { strcat(new->line, linebreak1); } len = esc_getlength(new->line); size = strlen(new->line); /* truncate old line if necessary */ if (linebreak) { *linebreak = 0; } /* re-allocate old line using smallest amount of space */ q = strdup(cur->line); free(cur->line); cur->line = q; /* attach new line to scroll */ dlist_append(mscroll, mscrollend, new); mscrollsize++; cur = new; } /* character fits; append it */ strncat(cur->line, p, 1); len++; } } scrollsize = nvar_default("scrollsize", SCROLLSIZE); while (scrollsize > 0 && mscrollsize > scrollsize) { /* limit the size of mscroll */ do { dlist_unlink_first(mscroll, mscrollend, cur); mscrollsize--; free(cur->line); free(cur); } while (mscroll && mscroll->own); } } /* clear the main scroll */ void clearscroll(void) { scroll_t *elt; dlist_forall_unlink(elt, mscroll, mscrollend) { free(elt->line); free(elt); } mscrollsize = 0; scur = NULL; dscr(wchan); } /* scroll to bottom */ void scrollbottom(void) { scur = NULL; dscr(wchan); } void dscr(WINDOW *win) { scroll_t *cur; int i, j, k, m, at=0, t, c; unsigned char bf = 0, uf = 0, gf = 0; char ebuf[6]; int col; /* column */ werase(win); wmove(win, 0, 0); if (scur == NULL) cur = mscrollend; else cur = scur; if (cur == NULL) return; i = win->_maxy-1; if (cur->chan && (wmode && cur->chan != curchan)) i++; while (i >= 0) { if (cur->prev == NULL) break; cur = cur->prev; if (cur->chan && (wmode && cur->chan != curchan)) continue; i--; } c = win->_maxy; for (j=0,i=0; i<=c; cur=cur->next) { if (cur == NULL) break; if (cur->chan && (wmode && cur->chan != curchan)) continue; if (!cur->own) { bf = 0; uf = 0; gf = 0; } wmove(win, j, 0); col = 0; for (k=0; cur->line[k] && col < COLS; k++) { if (cur->line[k] == '\e' && cur->line[k+1] == '[' && isdigit(cur->line[k+2])) { for (m=0; cur->line[k] && cur->line[k]!='m'; m++, k++) ebuf[m] = cur->line[k]; ebuf[m] = 'm'; ebuf[m+1] = '\0'; t = doesc(win, ebuf); if (t == COLOR_PAIR(CPW)) at = 0; else at |= t; } else if (cur->line[k] == 2) { if (!bf) { at |= doesc(win, BOLD); bf = 1; } else { at &= ~doesc(win, BOLD); bf = 0; } } else if (cur->line[k] == 31) { if (!uf) { at |= doesc(win, UNDERLINE); uf = 1; } else { at &= ~doesc(win, UNDERLINE); uf = 0; } } else if (cur->line[k] == 7) { if (!gf && i == c) beep(); gf = 1; } else if (cur->line[k] == 15) uf = bf = at = 0; else { waddch(win, cur->line[k]|at); col++; } } i++; j++; } scur = cur ? cur->prev : NULL; } void dscroll(WINDOW *win, int n) { int i; scroll_t *cur; if (scur == NULL) cur = mscrollend; else cur = scur; if (!cur) return; if (n > 0) { i = n; if (cur->chan && (wmode && cur->chan != curchan)) i++; while (i > 0) { if (cur->prev == NULL) break; cur = cur->prev; if (cur->chan && (wmode && cur->chan != curchan)) continue; i--; } } else if (n < 0) { i = n; if (cur->chan && (wmode && cur->chan != curchan)) i--; while (i < 0) { if (cur->next == NULL) { cur = NULL; break; } cur = cur->next; if (cur->chan && (wmode && cur->chan != curchan)) continue; i++; } } else return; scur = cur; dscr(win); drw(win); } int doesc(WINDOW *win, const char *in) { int i; for (i=0;;i++) { if (!colortab[i].in) return(0); if (!strcmp(colortab[i].in, in)) break; } if (colortab[i].c) return(COLOR_PAIR(colortab[i].pair)); else return(colortab[i].pair); } int input(WINDOW *win, sock_t *m) { chtype ebuf = 0; sock_t *t; int g; int j, s, n; char *msg; char *command; cmds_t *elt; t = findsock("server"); s = t ? t->fd : -1; ebuf = wgetch(winput); if (ebuf == '\e') { /* ESC */ ebuf = wgetch(winput); if (ebuf == ERR) { return(1); } else { ebuf+=128; } } switch (ebuf) { case '\n': /* Newline */ case '\r': /* Return */ /* enter the current line (cbuf) in the command history, unless it is a repetition of the previous command, or unless it is empty. */ if (*cbuf && (!cmdlend || strcmp(cbuf, cmdlend->cmd))) { elt = (cmds_t *)malloc(sizeof(cmds_t)); elt->cmd = strdup(cbuf); elt->prev = cmdlend; elt->next = NULL; if (cmdlend) { cmdlend->next=elt; } else { cmdl=elt; } cmdlend=elt; cmdlsize++; /* make sure command history does not get too long */ if (cmdlsize > BACKLOG) { elt = cmdl->next; free(cmdl->cmd); free(cmdl); cmdl = elt; cmdl->prev = NULL; cmdlsize--; } } /* remember command from cbuf for execution below */ command = strdup(cbuf); /* get ready for new input (we do this before the command is executed, because the command might cause a switch to another screen) */ ccmd = NULL; cbuf[0]=0; curx = 0; curr = 0; indraw(); ebuf = 0; if (*command == 0 || !strcmp(command, "/")) { /* do nothing, just print an empty line to give visual feedback */ wp(win, "\n"); drw(win); } else if (*command == '/') { lpbrk = 0; /* clear previous loop interrupt request */ n = parseout(s, command+1, win); indraw(); /* necessary because command could have been "/query" etc */ dstatus(); } else if (!curchan) { wp(win, "%s* You are not on a channel. Commands start with \"/\".%s\n", RED, WHITE); drw(win); } else if (curchan->q == 1) { msg = fixquotes(strdup(command)); sendpack(s, NAP_TELL, "%s %s", curchan->nm, msg); recent = curchan; wp(win, "%s* --> (%s%s%s)%s %s\n", GREEN, WHITE, curchan->nm, GREEN, WHITE, msg); drw(win); free(msg); recent = NULL; } else if (curchan->q == 2) { ssock(ircsock, "PRIVMSG %s :%s\n", curchan->nm, command); recent = curchan; wp(win, "%s<%s%s%s>%s %s\n", BRIGHT(MAGENTA), WHITE, mnick, BRIGHT(MAGENTA), WHITE, command); drw(win); recent = NULL; } else { msg = fixquotes(strdup(command)); if (sendpack(s, NAP_SAY, "%s %s", curchan->nm, msg) == -1) { delsock(s); /* s is the server, or -1 if no server */ } free(msg); } /* if-else-else */ free(command); break; case 128+KEY_BACKSPACE: /* META-backspace */ case 128+127: /* META-delete */ case 128+8: /* META-backspace */ curx--; while (curx >= 0 && cbuf[curx] == ' ') { memmove(cbuf+curx, cbuf+curx+1, strlen(cbuf+curx+1)); cbuf[strlen(cbuf)-1] = 0; curx--; } while (curx >= 0 && cbuf[curx] != ' ') { memmove(cbuf+curx, cbuf+curx+1, strlen(cbuf+curx+1)); cbuf[strlen(cbuf)-1] = 0; curx--; } if (curx < 0) { cbuf[0] = 0; curx = 0; } else { curx++; } if (curx == 0) curr = 0; indraw(); break; case KEY_BACKSPACE: /* backspace */ case 127: /* delete */ case 8: /* backspace */ if (curx) { for (j=curx-1; cbuf[j]; j++) cbuf[j] = cbuf[j+1]; curx--; indraw(); } ebuf = 0; break; case 23: /* Ctrl-W */ cbuf[curx] = 0; curx--; while (curx >= 0 && cbuf[curx] == ' ') { cbuf[curx] = 0; curx--; } while (curx >= 0 && cbuf[curx] != ' ') { cbuf[curx] = 0; curx--; } curx++; indraw(); break; case 24: /* Ctrl-X */ nextchan(); indraw(); /* If in window mode, redraw the screen */ if (wmode) { dscr(wchan); drw(wchan); } dstatus(); ebuf = 0; break; case 21: /* Ctrl-U */ cbuf[0] = 0; curx = 0; curr = 0; indraw(); ebuf = 0; break; case 11: /* Ctrl-K */ cbuf[curx] = 0; indraw(); ebuf = 0; break; case 1: /* Ctrl-A */ case KEY_HOME: /* Home */ case KEY_FIND: /* Find - a kind of home key */ curx = 0; indraw(); ebuf = 0; break; case 5: /* Ctrl-E */ case KEY_END: /* End */ case KEY_SELECT: /* Select - a kind of end key */ curx = strlen(cbuf); indraw(); ebuf = 0; break; case 4: /* Ctrl-D */ case 330: /* Delete */ if (cbuf[curx]) { memmove(cbuf+curx, cbuf+curx+1, strlen(cbuf+curx+1)+1); } indraw(); ebuf = 0; break; case 154: /* Ctrl-Meta-Z ??? */ ebuf = 0; break; case '\t': /* Tab */ ebuf = 0; for (g=curx; cbuf[g]!=' ' && g>=0; g--); if (cbuf[g] != ' ') g = 0; if (*cbuf == '/' && !g) { alias_t *al; for (al=alhead;al;al=al->next) if (!strncasecmp(cbuf+1, al->nm, strlen(cbuf+1))) { memset(cbuf, 0, sizeof(cbuf)); cbuf[0] = '/'; strcpy(cbuf+1, al->nm); strcat(cbuf, " "); curx = strlen(cbuf); indraw(); break; } for (j=0;out[j].func;j++) if (!strncasecmp(cbuf+1, out[j].nm, strlen(cbuf+1)) && out[j].help) { memset(cbuf, 0, sizeof(cbuf)); cbuf[0] = '/'; strcpy(cbuf+1, out[j].nm); strcat(cbuf, " "); curx = strlen(cbuf); indraw(); break; } } else if (curchan && curchan->users) { user_t *usr; int k, z; for (k=curx;cbuf[k]!=' '&&k>=0;k--); if (cbuf[k] == ' ') z = k+1; else z = 0; for (usr=curchan->users;usr;usr=usr->next) if (!strncasecmp(cbuf+z, usr->nm, strlen(cbuf+z))) { for (k=z;k<=curx;k++) cbuf[k] = 0; strcpy(cbuf+z, usr->nm); if (!z) strcat(cbuf, ": "); curx = strlen(cbuf); indraw(); break; } } break; case 20: /* Ctrl-T */ if (!curchan || !curchan->topic) tind = 0; else { if (tind >= (strlen(curchan->topic)-(COLS-(strlen(VERSION)+8)-4))) tind = 0; else tind += 5; } ebuf = 0; dstatus(); break; case KEY_PPAGE: /* PgUp */ case 16: /* Ctrl-P */ dscroll(win, (LINES-2)/2); indraw(); ebuf = 0; break; case KEY_NPAGE: /* PgDn */ case 14: /* Ctrl-N */ case 22: /* Ctrl-V */ dscroll(win, -(LINES-2)/2); indraw(); ebuf = 0; break; case 12: /* Ctrl-L */ clearok(wchan, 1); drw(wchan); drw(sep); drw(winput); if (!info.notop) { drw(whead); } dstatus(); dscr(wchan); drw(wchan); indraw(); ebuf = 0; break; case KEY_F(1): /* F1 */ case 128 + '1': /* M-1 */ return(1); break; case KEY_F(2): /* F2 */ case 128 + '2': /* M-2 */ switchtoscreen(RESULT_SCREEN); return(1); break; case KEY_F(3): /* F3 */ case 128 + '3': /* M-3 */ switchtoscreen(DLUL_SCREEN); return(1); break; case KEY_UP: /* UP */ if (ccmd == NULL) { if (cmdlend != NULL) { strcpy(cscratch, cbuf); ccmd = cmdlend; strcpy(cbuf, ccmd->cmd); curx = strlen(cbuf); } } else { if (ccmd->prev != NULL) { ccmd = ccmd->prev; strcpy(cbuf, ccmd->cmd); curx = strlen(cbuf); } } indraw(); break; case KEY_DOWN: /* DOWN */ if (ccmd) { ccmd = ccmd->next; if (ccmd == NULL) { strcpy(cbuf, cscratch); curx = strlen(cbuf); } else { strcpy(cbuf, ccmd->cmd); curx = strlen(cbuf); } } indraw(); break; case KEY_RIGHT: /* RIGHT */ if (cbuf[curx]) { curx++; } indraw(); break; case KEY_LEFT: /* LEFT */ if (curx) { curx--; } indraw(); break; default: /* printable characters? */ if ((32 <= ebuf && ebuf <= 126) || (160 <= ebuf && ebuf <=255)) { j = strlen(cbuf); if (j_maxx+1; LINES = w->_maxy+1; */ /* dolc(); */ start_color(); cbreak(); noecho(); bgcolor = COLOR_BLACK; #ifdef HAVE_ASSUME_DEFAULT_COLORS if (info.transparent) { assume_default_colors(COLOR_WHITE, -1); bgcolor = -1; } #endif init_pair(1, COLOR_WHITE, COLOR_BLUE); init_pair(CPR, COLOR_RED, bgcolor); init_pair(CPG, COLOR_GREEN, bgcolor); init_pair(CPW, COLOR_WHITE, bgcolor); init_pair(CPB, COLOR_BLUE, bgcolor); init_pair(CPY, COLOR_YELLOW, bgcolor); init_pair(CPM, COLOR_MAGENTA, bgcolor); init_pair(CPC, COLOR_CYAN, bgcolor); init_pair(CPWR, COLOR_WHITE, COLOR_RED); init_pair(CPWB, COLOR_WHITE, COLOR_BLUE); winput = newwin("input", 1, 0, LINES-1, 0); sep = newwin("sep", 1, 0, LINES-2, 0); if (!info.notop) { wchan = newwin("chan", LINES-3, 0, 1, 0); whead = newwin("head", 1, 0, 0, 0); } else wchan = newwin("chan", LINES-2, 0, 0, 0); nodelay(winput, TRUE); wattrset(sep, COLOR_PAIR(1)); if (!info.notop) wattrset(whead, COLOR_PAIR(1)); idlok(wchan, FALSE); scrollok(wchan, TRUE); wbkgdset(winput, COLOR_PAIR(CPW)); wbkgdset(wchan, COLOR_PAIR(CPW)); /* bkgd(COLOR_PAIR(1)); */ keypad(winput, TRUE); keypad(stdscr, TRUE); indraw(); /* tcgetattr(0, &ts); printf("%i\n", ts.c_iflag&ISTRIP); exit(1); */ dstatus(); } /* draw the input area of the main window. This depends on the * following: * * cbuf: the text currently being edited by the user * curx: the current cursor position within buf (0 <= strlen(buf) <= curx) * curr: the first character of buf that is actually visible (this is * a global variable and we update it here - the only other two * places where it's updated are two places in input().) * curchan, curchan->nm, and curchan->q: this determines whether or not * the current channel/query should be printed at the beginning of * the line. * COL: the current width of the screen. * **/ void indraw() { int i, b; int cols = COLS; /* trick compiler into allowing t[COLS+1] */ int ucols; /* columns not taken up by channel */ unsigned char t[cols+1]; /* the entire line to be output, plus 0 */ t[cols]=0; /* print the channel portion of the line */ if (curchan && cols>=3) { char *p = strdup(curchan->nm); if (strlen(curchan->nm) > (cols/4)) p[cols/4] = 0; sprintf(t, curchan->q ? "(%s) " : "[%s] ", p); free(p); } else { *t=0; } ucols = cols-strlen(t); /* first adjust curr with respect to curx */ while (curx >= curr+ucols) curr += ucols/4 ? ucols/4 : 1; while (curx < curr) curr -= ucols/4 ? ucols/4 : 1; /* now curx is in the window defined by curr, unless ucols==0. */ /* now adjust curr with respect to cbuf, to make sure there is no empty space on the left, and preferably none on the right. Notice this cannot move the cursor out of the window. */ if (curr+ucols>strlen(cbuf)+1 && curr) curr = strlen(cbuf)+1-ucols; if (curr < 0) curr = 0; /* assemble the line */ strncat(t, cbuf+curr, ucols); memset(t+strlen(t), ' ', cols-strlen(t)); /* and print it. */ werase(winput); for (i=0;i= cols) b = cols-1; /* move the cursor */ wmove(winput, 0, b); drw(winput); } /* not used */ unsigned char gchr(WINDOW *win) { fd_set fs; struct timeval tv; unsigned char r; FD_ZERO(&fs); FD_SET(0, &fs); tv.tv_sec = 0; tv.tv_usec = 50000; if (!select(1, &fs, NULL, NULL, &tv)) return(0); r = wgetch(win); if (r == '\e') { ungetch('\e'); return(0); } return(r); } nap-1.5.4.orig/src/getline.h0000644000175000017500000000622607777577244013501 0ustar dzdz/* This file was contributed by Suzanne Skinner and is copyrighted under the GNU General Public License. (C) 2002 Suzanne Skinner. The code contained in this file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* getline is a more flexible, display-independent readline library. It * ties in with the dynstr library in order to provide command-line editing * on lines of arbitrary length. It calls no display or output functions, * acting solely as a back-end. * * There is only one important user-visible function: gl_handle_keystroke. Call * it whenever you've read an input keystroke. gl_handle_keystroke takes a * pointer to the current string, a prefix length (see below), an integer * cursor (0-based), and a chtype value representing the keystroke. It returns * the updated cursor, or, if the user typed a key bound to glf_done (most * likely ENTER), returns GL_DONE to indicate that the input is complete, * or GL_ABORT to indicate that the input was aborted. * * If a non-0 prefix length, L, is specified, the user will not be able to * edit or cursor over the first L characters of the given string. * * This library includes ncurses.h to provide chtype, but does not otherwise * depend on ncurses. * * Default keybindings are defined in the array gl_keybindings. They may be * user configurable in the future; for now, you'll have to edit getline.c * directly. * * getline keeps an input history, much like readline, retaining up to * GL_HISTORY_MAXLEN-1 past inputs. However, note that only one history * record is kept for all calls to gl_handle_keystroke in a program. */ #ifndef GETLINE_H #define GETLINE_H #include #define GL_DONE -1 #define GL_ABORT -2 #define GL_HISTORY_MAXLEN 50 #define GL_FUNC(name) int name(dynstr *str, int prefix_len, int cursor) typedef int (*gl_func)(dynstr *, int, int); typedef struct gl_keybinding_struct { chtype key; gl_func handler; } gl_keybinding; typedef struct gl_history_entry_struct { char *line; struct gl_history_entry_struct *next; struct gl_history_entry_struct *prev; } gl_history_entry; int gl_handle_keystroke(dynstr *str, int prefix_len, int cursor, chtype keystroke); GL_FUNC(glf_cursor_left); GL_FUNC(glf_cursor_right); GL_FUNC(glf_beginning_of_line); GL_FUNC(glf_end_of_line); GL_FUNC(glf_delete_char_back); GL_FUNC(glf_delete_char_forward); GL_FUNC(glf_delete_all); GL_FUNC(glf_delete_to_end); GL_FUNC(glf_history_back); GL_FUNC(glf_history_forward); GL_FUNC(glf_abort); GL_FUNC(glf_done); #endif nap-1.5.4.orig/src/title.h0000644000175000017500000000116707665513200013144 0ustar dzdz/* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ char title[] = " _.-------._\n" " |\\ /|\n" " /| \\_.----._/ |\\ __\n" " .$: :$. _____ ____ _____ _____ / /__ ___ ____\n" " |$$: ___ ___ :$$| / __ // _ `// _ // ___// __// _ \\ / ___/\n" " \"$: \\___\\/___/ :$\" / / / // /_/ // /_/ /(__ )/ /_ / __// /\n" " | __ | /_/ /_/ \\__,_// ____//_____/ \\___/ \\___//_/mG!\n" " `. \\/ .' /_/\n" " `. .__, .'\n" " `----'\n" "\n" ; nap-1.5.4.orig/src/event.c0000644000175000017500000010613307575445633013154 0ustar dzdz/* Copyright (c) 2000 Kevin Sullivan * * Please refer to the COPYRIGHT file for more information. */ /* This file contains functions that are used to handle socket events. The scheduler for these events (main loop) is in scheck.c. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "alias.h" #include "codes.h" #include "colors.h" #include "defines.h" #include "event.h" #include "scheck.h" #include "nap.h" #include "sscr.h" #include "cmds.h" #include "scmds.h" #include "timer.h" #include "winio.h" #include "lists.h" #ifdef MEMWATCH #include "memwatch.h" #endif extern upload_t *up; extern download_t *down; extern info_t info; extern int srch; /* 1 while search or browse is in progress */ extern struct inbrowse_s directbrowse; int noprint=0; /* not used */ void initssock(int port) { struct sockaddr_in frm; int s, on = 1; s = socket(AF_INET, SOCK_DGRAM, 0); frm.sin_addr.s_addr = INADDR_ANY; frm.sin_port = htons(port); frm.sin_family = AF_INET; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); setkeepalive(s); bind(s, (struct sockaddr *)&frm, sizeof(frm)); addsock(s, "ssock", S_R, inssock); } /* not used */ int inssock(WINDOW *win, sock_t *m) { char buf[1024]; /* note: don't need malloc */ struct sockaddr_in frm; int frmlen = sizeof(frm); memset(buf, 0, 1024); recvfrom(m->fd, buf, 1024, 0, (struct sockaddr *)&frm, &frmlen); if (!strncmp(buf, "VERSION", strlen("VERSION"))) { if (strcmp(strchr(buf, ' ')+1, VERSION)) { wp(win, "%s* Attention: Version %s of nap is out!%s\n", BRIGHT(BLUE), strchr(buf, ' ')+1, WHITE); wp(win, "%s* Attention: Please visit http://www.gis.net/~nite/ to upgrade immediately%s\n", BRIGHT(BLUE), WHITE); drw(win); } } else if (!strncmp(buf, "MSG", strlen("MSG"))) { wp(win, "%s* %s%s\n", BRIGHT(BLUE), strchr(buf, ' ')+1, WHITE); drw(win); } return(1); } /* "ipc" stands for "inter process communication". This is simply a * pipeline, created at the beginning of main(). It is used by child * processes to send output to the main screen. For instance, when * doing time-consuming things such as rebuilding the library, we fork * a child, but the child must then be able to send output to the main * screen. Using wp() directly won't work, both because the output * would be asynchronous, and because the child can't update the * parents' data structures. * * The reading end of the connection is here, and simply prints any * received data to the main screen. The sending happens in the many * calls in cmds.c of the form * * ssock(ipcs[1], "* Successfully rebuilt your library\n"); */ /* receive on ipc socket */ int inipc(WINDOW *win, sock_t *m) { int s = m->fd; char *buf; rsock(s, &buf); if (!buf) return(1); /* addscroll(win, buf); dscr(win); */ wp(win, buf); /* use wp so the output goes to the log file also */ drw(win); free(buf); return(1); } /* receive from server socket */ int inserv(WINDOW *win, sock_t *m) { int s = m->fd, j, n, r; phead_t *pk; char *data; r = recvpack(s, &data, &pk); if (r == -2) return(1); else if (r == -1) { wp(win, ""RED"* Error: %s"WHITE"\n", strerror(errno)); drw(win); delsock(m->fd); return(1); } else if (r == -3) { wp(win, ""RED"* Error: unexpected end of file from server"WHITE"\n"); drw(win); delsock(m->fd); return(1); } for (j=0;data[j];j++) if (data[j] == 10) { strncpy(data+j, data+j+1, strlen(data+j+1)); data[strlen(data)-1] = 0; } n = parsein(s, pk->op, data, win); noprint = 0; if (n == -1) { delsock(m->fd); return(1); } else if (n == -2) return(-1); /* don't know what this does, or used to do. Don't know of a concrete situation where parsein returns -2, or in fact -1. */ free(pk); free(data); dstatus(); return(1); } /* a remote client has connected to our data port; we just accept the connection and then listen on the dedicated port for that connection */ int gconn(WINDOW *win, sock_t *m) { int s = m->fd, r; struct sockaddr_in frm; int frmlen = sizeof(frm); r = accept(s, (struct sockaddr *)&frm, &frmlen); if (r == -1) return(1); setkeepalive(s); addsock(r, "conn", S_R, lsock); ssock(r, "1"); return(1); } /* a remote client has connected to us and is about to say "GET", "SEND", * "GETLIST", or "SENDLIST" (the latter two are for direct browsing) */ int lsock(WINDOW *win, sock_t *m) { char buf[8]; int r; memset(buf, 0, sizeof(buf)); r = recv(m->fd, &buf, sizeof(buf), MSG_PEEK); if (r==-1) { wp(win, ""RED"* Bogus connection from remote client (%s): %s"WHITE"\n", getpeerip(m->fd), strerror(errno)); drw(win); delsock(m->fd); return(1); } /* GET and SEND are prefixes of GETLIST and SENDLIST respectively, * so have to check for the longer words first */ if (!strncmp(buf, "GETLIST", 7)) { recv(m->fd, &buf, 7, 0); m->func = dogetlist; m->t = S_W; /* prepare to write */ } else if (!strncmp(buf, "SENDLIST", 8)) { recv(m->fd, &buf, 8, 0); /* we rename the connection here so that we can find it and delete it * if the direct browse request times out. This is necessary because * a broken client like Napster v2.0 BETA 9.6 will send a SENDLIST and * nothing else. As a result, dosendlist will never be called, and the * socket will remain open until the program quits. */ free(m->socknm); m->socknm = strdup("sendlist"); m->func = dosendlist; } else /* note: trailing "else" goes with following "if"!! */ if (!strncmp(buf, "GET", 3)) { recv(m->fd, &buf, 3, 0); m->func = doget; } else if (!strncmp(buf, "SEND", 4)) { recv(m->fd, &buf, 4, 0); m->func = dosend; } else { char *data=NULL; /* see what the peer was saying */ r = rsock(m->fd, &data); wp(win, ""RED"* Bogus connection from remote client (%s) [%s]"WHITE"\n", getpeerip(m->fd), data ? quote(data) : ""); drw(win); ssock(m->fd, "INVALID REQUEST\n"); free(data); delsock(m->fd); return(1); } return(1); } /* remote client connected to our data port and issued a GET command */ int doget(WINDOW *win, sock_t *m) { char *buf, *nick, *rfn; size_t bsz; upload_t *task; struct stat st; sock_t *sv; char **tok; int i, cnt; FILE *f; if (rsock(m->fd, &buf) == -1) { delsock(m->fd); return(1); } tok = form_tokso(buf, &cnt); /* we should be able to use form_tokso() here instead of the more general * form_toks() */ /* the client should have sent a string of the form * "" */ if (cnt < 3) { wp(win, ""RED"* Bogus GET command from remote client (%s) [GET%s]"WHITE"\n", getpeerip(m->fd), quote(buf)); drw(win); ssock(m->fd, "INVALID REQUEST\n"); free(buf); for (i=0;ifd); return(1); } nick = strdup(tok[0]); rfn = strdup(tok[1]); bsz = strtoul(tok[2], 0, 10); free(buf); for (i=0;inick, nick) && !strcasecmp(task->rfn, rfn) && task->state==WAITING); if (!task) { /* the following error message is often a result of an upload request which we rejected, but we sent an accept message to the server. It is more likely to be confusing than useful to the user, so we omit it. */ /* wp(win, "%s* %s requested upload of \"%s\" but it isn't in the upload list! (GET)%s\n", RED, nick, rfn, WHITE); drw(win); */ ssock(m->fd, "INVALID REQUEST\n"); free(nick); free(rfn); delsock(m->fd); return(1); } free(nick); free(rfn); /* otherwise accept the request. */ /* Open the local file for reading. Note: we already checked that this file was in the shared library before we created this task. Thus, the local file *should* exist. However, it might be unreadable, or the library might be out of date. */ f = fopen(task->lfn, "rb"); if (!f) { wp(win, ""RED"* \"%s\" not found (requested by %s)"WHITE"\n", task->lfn, task->nick); drw(win); ssock(m->fd, "FILE NOT FOUND\n"); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* determine file size */ fstat(fileno(f), &st); if (bsz > st.st_size) /* note: bsz is unsigned, thus bsz<0 impossible */ { wp(win, ""RED"* Error sending file \"%s\" to %s: illegal offset requested (%lu/%lu)"WHITE"\n", task->fn, task->nick, (long)bsz, (long)st.st_size); drw(win); ssock(m->fd, "INVALID REQUEST\n"); fclose(f); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } fseek(f, bsz, SEEK_SET); /* go to state IN_PROGRESS */ task->sk = m; task->f = f; task->size = st.st_size; task->bsz = bsz; task->pos = bsz; task->p_time = time(0); task->state = IN_PROGRESS; /* link task to socket */ m->utask = task; m->bwlimit = 1; bandwidth_init(&m->bw); m->func = sfile; m->t = S_W; free(m->socknm); m->socknm = strdup(gnum(1)); sv = findsock("server"); if (sv) sendpack(sv->fd, NAP_UP, NULL); /* send the file size */ ssock(m->fd, "%lu", (long)task->size); wp(win, "* Sending file \"%s\" to %s (%lu bytes)\n", task->fn, task->nick, (long)task->size); drw(win); return(1); } /* we requested a file from a firewalled client. The remote client has * connected to us and is about to start uploading the file */ int dosend(WINDOW *win, sock_t *m) { char *buf, *nm, *rfn, *fn, *lfn; FILE *f; size_t size; download_t *task; sock_t *sv; char **tok; int i, r, cnt; if (rsock(m->fd, &buf) == -1) { delsock(m->fd); return(1); } tok = form_tokso(buf, &cnt); /* the remote client should have sent a string of the form * "" */ if (cnt < 3) { wp(win, ""RED"* Bogus SEND command from remote client (%s) [SEND%s]"WHITE"\n", getpeerip(m->fd), quote(buf)); drw(win); ssock(m->fd, "INVALID REQUEST\n"); free(buf); for (i=0;ifd); return(1); } nm = strdup(tok[0]); rfn = strdup(tok[1]); size = strtoul(tok[2], 0, 10); free(buf); for (i=0;ifd); return(1); } list_find(task, down, !strcasecmp(task->nick, nm) && !strcasecmp(task->rfn, rfn) && task->state==WAITING); fn = ud_basename(rfn); /* note: fn is a pointer into rfn! Do not free rfn while fn is still needed. */ if (!size) { rsock(m->fd, &buf); wp(win, "* Error downloading \"%s\" from %s (returned a size of 0) " \ "[%s]\n", fn, nm, buf?quote(buf):""); drw(win); if (task) { free(task->check); task->state = FAILED; task->d_time = time(0); } free(rfn); free(nm); delsock(m->fd); return(1); } if (!task) { /* this error is frequently the result of a download request which timed out before the remote client got in touch with us. We omit the error message, since it is confusing and not useful */ /* wp(win, "%s* Error: %s tried to send (push) \"%s\", but we did not request it!%s\n", RED, nm, fn, WHITE); drw(win); */ free(nm); free(rfn); delsock(m->fd); return(1); } /* try to open local file for this download */ r = opendownloadfile(fn, &f, &lfn); if (r==-1) { wp(win, ""RED"* Error: could not open local file \"%s\": %s"WHITE"\n", lfn, strerror(errno)); drw(win); free(lfn); } if (r==-1 || r==-2) { free(nm); free(rfn); free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } free(nm); free(rfn); task->sk = m; task->lfn = lfn; task->f = f; task->size = size; task->bsz = 0; task->pos = 0; task->p_time = time(0); task->state = IN_PROGRESS; /* rename connection from "conn" to "d #", and connect it to this task */ free(m->socknm); m->socknm = strdup(gnum(0)); m->dtask = task; m->bwlimit = 1; bandwidth_init(&m->bw); m->func = gfile; sv = findsock("server"); if (sv) sendpack(sv->fd, NAP_DOWN, NULL); /* send offset */ ssock(m->fd, "%lu", (long)0); return(1); } /* try to open a port that is specified by the string dataport. Dataport must either be a port number such as "6699" or a range such as "6699-6799". Return port number used if successful, or -1 if failure (with errno set). If port 0 is requested, return 0 without opening anything - this probably was configured by the user if we're behind a firewall. */ int initfserv(char *dataport) { struct sockaddr_in me; int s, on = 1; int port, first, last; char *p; if (!dataport) return(0); /* parse dataport */ first = last = strtol(dataport, &p, 10); while (p && isspace(*p)) { p++; } if (p && *p=='-') { /* range given? parse second part */ last = strtol(p+1, &p, 10); } if (!p || *p!='\0') { /* parse error */ errno = EINVAL; return -1; } s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) return(-1); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); setkeepalive(s); for (port = first; port <= last; port++) { me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(port); me.sin_family = AF_INET; if (bind(s, (struct sockaddr *)&me, sizeof(me)) != -1) { /* success */ listen(s, 5); addsock(s, "fserv", S_R, gconn); return(port); } } return(-1); /* overall failure */ } void closefserv() { sock_t *sk; sk = findsock("fserv"); if (!sk) return; delsock(sk->fd); } /* We are about to upload a file to a remote client. We had to initiate * the connection because we are firewalled and cannot accept incoming * connections. The upload is in state CONNECTING. */ int initsend(WINDOW *win, sock_t *m) { int s = m->fd, r; upload_t *task = m->utask; sock_t *sk; struct stat st; char c; FILE *f; /* read the initial "1" from remote client */ if (recv(s, &c, 1, 0) <= 0) { wp(win, "%s* Error sending file \"%s\" to %s: connection refused by remote client%s\n", RED, task->fn, task->nick, WHITE); drw(win); task->state=FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* Open the local file for reading. Note: we already checked that this file was in the shared library before we created this task. Thus, the local file *should* exist. However, it might be unreadable, or the library might be out of date. */ f = fopen(task->lfn, "rb"); if (!f) { wp(win, ""RED"* \"%s\" not found (requested by %s)"WHITE"\n", task->lfn, task->nick); drw(win); task->state=FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* determine file size */ fstat(fileno(f), &st); r = ssock(s, "SEND"); /* send "mynick filename filesize" */ r = ssock(s, "%s \"%s\" %lu", info.user, task->rfn, st.st_size); if (r <= 0) { wp(win, ""RED"* Error sending file (%s) to %s: %s%s"WHITE"", RED, task->rfn, task->nick, r ? strerror(errno) : "remote client is misconfigured"); drw(win); sk = findsock("server"); if (sk) sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick); fclose(f); task->state=FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* go to state CONNECTING1, continue with ssize() */ task->state = CONNECTING1; task->f = f; task->size = st.st_size; m->func = ssize; m->t = S_R; return(1); } /* continue what was started by initsend. Next the remote (firewalled) client will send the byte offset. Upload's state is CONNECTING1. */ int ssize(WINDOW *win, sock_t *m) { char buf[32]; int r; upload_t *task = m->utask; size_t bsz; memset(buf, 0, 32); r = recv(m->fd, buf, sizeof(buf), 0); if (r<=0) { wp(win, ""RED"* Error sending file \"%s\" to %s: %s"WHITE"\n", task->fn, task->nick, r ? strerror(errno) : "did not receive a proper offset"); drw(win); fclose(task->f); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } bsz = strtoul(buf, 0, 10); if (bsz > task->size) { wp(win, ""RED"* Error sending file \"%s\" to %s: illegal offset requested (%lu/%lu)"WHITE"\n", task->fn, task->nick, (long)bsz, (long)task->size); drw(win); fclose(task->f); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } fseek(task->f, bsz, SEEK_SET); /* go to state IN_PROGRESS */ task->bsz = bsz; task->pos = bsz; task->p_time = time(0); task->state = IN_PROGRESS; m->bwlimit = 1; bandwidth_init(&m->bw); m->func = sfile; m->t = S_W; wp(win, "* Sending file \"%s\" to %s (%lu bytes)\n", task->fn, task->nick, (long)(task->size - bsz)); drw(win); return(1); } /* we have connected to a remote client and we are about to issue a request * for a file */ int initget(WINDOW *win, sock_t *m) { int s = m->fd, r; download_t *task = m->dtask; /* state of task is CONNECTING */ download_t *elt; sock_t *sk; char ch; /* remote client should send a '1' (ASCII character 49) */ r = recv(s, &ch, 1, 0); if (r <= 0) { wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "connection refused", WHITE); drw(win); free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* make sure the task is not stale */ list_find(elt, down, elt==task); if (!elt) { delsock(m->fd); return(1); } r = ssock(s, "GET"); r = ssock(s, "%s \"%s\" %lu", info.user, task->rfn, (long)0); if (r <= 0) { wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "remote client misconfigured", WHITE); drw(win); sk = findsock("server"); if (sk) sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick); free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } m->func = gsize; /* m->t = S_R; */ return(1); } /* continue the GET started by initget, now receive remote host's answer */ int gsize(WINDOW *win, sock_t *m) { char buf[32]; int i, s = m->fd; download_t *task = m->dtask; /* state is still CONNECTING */ sock_t *sk; int r; FILE *f; char *lfn; /* read file size. drscholl's napster spec says: * "keep reading until you hit a character that is not a digit" */ for (i=0; i<31; i++) /* but don't overflow buf[] ! */ { r = recv(s, &buf[i], 1, MSG_PEEK); if (r <= 0 && !i) { wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "remote client misconfigured", WHITE); drw(win); sk = findsock("server"); if (sk) sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick); free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } /* abort only if first character is not a digit. * this catches messages such as "INVALID REQUEST" or "FILE NOT SHARED" * but does not barf on ID3 tags that follow the file size. * (Before, an error was signaled if an alphabetic character * followed 0 or more numeric characters. This caused a problem with * mp3 files that start with ID3 tags.) -NBL */ if (!isdigit(buf[i]) && (i == 0)) { recv(s, buf, 32, 0); buf[31]=0; /* make sure it's 0 terminated */ wp(win, ""RED"* Error getting \"%s\" from %s [%s]"WHITE"\n", task->fn, task->nick, quote(buf)); drw(win); free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } if (!isdigit(buf[i])) break; recv(s, &buf[i], 1, 0); } /* get rid of the non-digit that was just read * (or if i reached 31, make sure that buf[] is '\0'-terminated) */ buf[i] = '\0'; /* we need the debugging code here, since we didn't call rsock for this */ if (nvar("debug") == 2) { wp(win, ""DARK GREEN"<-- [from %d=%s] <%s>"WHITE"\n", s, m->socknm, quote(buf)); drw(win); } /* try to open local file for this download */ r = opendownloadfile(task->fn, &f, &lfn); if (r==-1) { wp(win, ""RED"* Error: could not open local file \"%s\": %s"WHITE"\n", lfn, strerror(errno)); drw(win); free(lfn); } if (r==-1 || r==-2) { free(task->check); task->state = FAILED; task->d_time = time(0); delsock(m->fd); return(1); } task->lfn = lfn; task->f = f; task->size = strtoul(buf, 0, 10); task->bsz = 0; task->pos = 0; task->p_time = time(0); task->state = IN_PROGRESS; m->bwlimit = 1; bandwidth_init(&m->bw); m->func = gfile; return(1); } /* Sending data to a remote client. State is IN_PROGRESS */ int sfile(WINDOW *win, sock_t *m) { char buf[2048], *start, *end; upload_t *task = m->utask; FILE *f; int n, r; time_t t; /* is this mix of low-level and high-level i/o safe? Why use FILE* object if using low-level i/o? -PS */ n = read(fileno(task->f), buf, sizeof(buf)); if (n <= 0) { t = time(0); wp(win, "* Finished sending \"%s\" to %s (%lu of %lu bytes in %lu seconds)\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t-task->p_time)); drw(win); if (info.logfile) { f = fopen(info.logfile, "a"); if (f) { start = strdup(ctime(&task->p_time)); start[strlen(start)-1] = 0; end = strdup(ctime(&t)); end[strlen(end)-1] = 0; fprintf(f, "S %s %s \"%s\" %s\n", start, task->nick, task->lfn, end); fclose(f); free(start); free(end); } } fclose(task->f); task->d_time = t; task->state = COMPLETE; delsock(m->fd); return(1); } r = send(m->fd, buf, n, 0); if (r <= 0) { t = time(0); wp(win, "* Transfer interrupted while sending \"%s\" to %s (%lu of %lu bytes in %lu seconds): %s\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t-task->p_time), r ? strerror(errno) : "connection lost?"); drw(win); if (info.logfile) { f = fopen(info.logfile, "a"); if (f) { start = strdup(ctime(&task->p_time)); start[strlen(start)-1] = 0; end = strdup(ctime(&t)); end[strlen(end)-1] = 0; fprintf(f, "SI %s %s \"%s\" %s\n", start, task->nick, task->lfn, end); fclose(f); free(start); free(end); } } fclose(task->f); task->d_time = t; task->state = INCOMPLETE; delsock(m->fd); return(1); } task->pos += n; /* update byte counts for bandwidth limiting */ bandwidth_register(&m->bw, n); bandwidth_register(&bwup, n); return(1); } /* ------------------------------------------------------------------------ */ /* we have connected to a remote client in order to issue a GETLIST command. * The connection was initiated in scmds.c:sbrowse2acc(). */ int initgetlist(WINDOW *win, sock_t *m) { int s = m->fd, r; char c; /* remote client should send a '1' (ASCII character 49) */ r = recv(s, &c, 1, 0); if (r <= 0) { wp(win, ""RED"* Error browsing %s: %s"WHITE"\n", directbrowse.nick, \ r ? strerror(errno) : "connection refused"); drw(win); directbrowse.state = FAILED; srch = 0; delsock(m->fd); return(1); } r = ssock(s, "GETLIST"); if (r <= 0) { wp(win, ""RED"* Error browsing %s: %s"WHITE"\n", directbrowse.nick, \ r ? strerror(errno) : "0 bytes written to socket"); drw(win); directbrowse.state = FAILED; srch = 0; delsock(m->fd); return(1); } /* still in CONNECTING state */ m->func = glistnick; /* wait for remote client to send its nick */ return(1); } /* ------------------------------------------------------------------------ */ /* after we issue a GETLIST command, the remote client sends it nick before * sending its shared file list. */ int glistnick(WINDOW *win, sock_t *m) { char *nick = NULL; FILE *f; /* we duplicate the file descriptor so the new descriptor can be closed * independently of the original one when fclose() is called. */ directbrowse.f = f = fdopen(dup(m->fd), "r"); /* remote client sends its nick as "\n" */ nick = nap_getline(f); /* nap_getline uses fgets() to read a line */ if (!nick) { wp(win, ""RED"* Error browsing %s: remote client did not send its nick"\ WHITE"\n", directbrowse.nick); drw(win); directbrowse.state = FAILED; srch = 0; fclose(f); /* closing the stream will also close the associated file descriptor, * but remember that this descriptor is a duplicate of m->fd, so * we can safely close m->fd. */ delsock(m->fd); return(1); } /* is this who we were expecting? */ if (strcasecmp(directbrowse.nick, nick) != 0) { wp(win, ""RED"* Error browsing %s: remote client reports nick as %s"\ WHITE"\n", directbrowse.nick, quote(nick)); drw(win); free(nick); directbrowse.state = FAILED; srch = 0; fclose(f); delsock(m->fd); return(1); } free(nick); wp(win, "* Receiving shared file list from %s...\n", directbrowse.nick); drw(win); directbrowse.state = IN_PROGRESS; m->func = glist; return(1); } /* ------------------------------------------------------------------------ */ /* receive a shared file list from a remote client, one line per call */ int glist(WINDOW *win, sock_t *m) { char *buf; char **tok; char *tmptok[7]; int cnt, i; FILE *f = directbrowse.f; /* remote client sends a list of files consisting of lines like * ""