Commit 70a429cd authored by johan's avatar johan
Browse files

Merge branch 'master' into zrtphash

Conflicts:
	coreapi/linphonecall.c
parents 02ebeac3 aa91757d
......@@ -39,6 +39,7 @@
<fileInfo id="0.2079208171.2090246372" name="ringback.wav" rcbsApplicability="disable" resourcePath="tester/sounds/ringback.wav" toolsToInvoke=""/>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="coreapi"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="daemon"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gtk"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="include"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="tester"/>
......
......@@ -55,12 +55,18 @@ coreapi/help/realtimetext_sender
coreapi/test_ecc
coreapi/test_lsd
gtk/version_date.h
daemon/linphone-daemon
daemon/linphone-daemon-pipetest
*.la
*.lo
*.deps
*.libs
share/certdata.txt
coreapi/test_numbers
specs.c
*.orig
*.rej
*.kdev4
*.lo
*.la
*.swp
.deps
.libs
......@@ -69,7 +75,6 @@ tools/test_lsd
tools/test_numbers
coreapi/help/notify
share/fresh-rootca.pem
share/certdata.txt
tester/liblinphone_tester
tools/lp-gen-wrappers
tools/lpc2xml_test
......
......@@ -105,7 +105,7 @@ if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
else()
find_package(BelleSIP REQUIRED)
find_package(Mediastreamer2 REQUIRED)
find_package(BcToolbox REQUIRED OPTIONAL_COMPONENTS tester)
find_package(BcToolbox 0.0.3 REQUIRED OPTIONAL_COMPONENTS tester)
endif()
find_package(XML2 REQUIRED)
find_package(Zlib)
......
......@@ -4,8 +4,7 @@
ACLOCAL_AMFLAGS = -I m4 $(ACLOCAL_MACOS_FLAGS)
SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
coreapi console gtk share scripts tools tester include
coreapi console gtk share scripts tools daemon tester include
GITVERSION=`cd $(top_srcdir) && git describe --always || echo $(VERSION)`
......@@ -62,6 +61,30 @@ EXTRA_DIST = BUGS \
$(LINPHONEDEPS_FILELIST) \
$(ISS_SCRIPT).in
EXTRA_DIST += CMakeLists.txt \
cmake/FindGtkMacIntegration.cmake \
cmake/FindIconv.cmake \
cmake/FindIntl.cmake \
cmake/FindNotify.cmake \
cmake/FindSqlite3.cmake \
cmake/FindXML2.cmake \
cmake/FindZlib.cmake \
cmake/LinphoneConfig.cmake.in \
config.h.cmake \
console/CMakeLists.txt \
coreapi/CMakeLists.txt \
coreapi/gitversion.cmake \
coreapi/help/CMakeLists.txt \
gtk/CMakeLists.txt \
java/CMakeLists.txt \
pixmaps/CMakeLists.txt \
po/CMakeLists.txt \
share/CMakeLists.txt \
share/rings/CMakeLists.txt \
share/rootca.cmake \
tester/CMakeLists.txt \
tools/CMakeLists.txt
DISTCLEANFILES= $(ISS_SCRIPT) $(PACKAGE_WIN32_FILELIST)
CLEANFILES=Portfile Portfile-devel
......
SUBDIRS=macos
EXTRA_DIST = openembedded
Recipes for open embedded: http://www.openembedded.org
Documentations:
http://docs.openembedded.org/usermanual/
http://bitbake.berlios.de/manual/
Instructions for compilation from sources: (requires 10 Go of free space)
- Choose a distribution and build it.
For example, to build Angstrom follow the guide at http://www.angstrom-distribution.org/building-angstrom
For IGEPv2 use environment variable MACHINE=igep0020
It is possible to use MACHINE=qemuarm to build an image that can be run on a computer with qemu.
- Add linphone recipes to the pool with an higher priority:
Edit conf/bblayers.conf to set EXTRALAYERS to point to the source repository of linphone. Search the EXTRALAYERS definition in conf/bblayers.conf
and modify it like this:
# Add your overlay location to EXTRALAYERS
# Make sure to have a conf/layers.conf in there
EXTRALAYERS ?= "/home/smorlat/sources/git/linphone-daemon/build/openembedded"
This additional layer gives access to the various linphone recipes but also to a recipe to build an entire image containing linphone.
To build this image based on the generic console image you will need to use:
bitbake console-linphone-image
- Prepare compilation
Source appropriate environment with "~/.oe/enviro*"
Change directory to where you launched Angstrom install script.
- Compile linphone
bitbake -c clean linphone
bitbake linphone
- If you want additional codecs (e.g. iLBC or AMR) compile linphone-plugins
bitbake -c clean linphone-plugins
bitbake linphone-plugins
- Find the generated packages "*.ipk"
Example: /Data/work/angstrom/angstrom-setup-scripts/build/tmp-angstrom_2008_1/deploy/glibc/ipk/armv7a/
Installation
- check network connectivity
* ping linphone.org
* see "route -n"
* see "/etc/resolv.conf"
- update package list
* opkg update
- copy ipk files to install to /tmp
- eventually remove previously installed packages
- install with "opkg install libortp*.ipk libmediastreamer*.ipk liblinphone*.ipk linphonec*.ipk"
DESCRIPTION = "Linphone version of antlr3"
LICENSE = "GPL"
PROVIDES = "antlr3c antlr3c-dev"
ALLOW_EMPTY_${PN} = "1"
S = "${WORKDIR}/git/runtime/C"
inherit autotools pkgconfig lib_package
do_fetch_append() {
import os
os.system("autogen.sh")
}
require antlr3c.inc
SRCREV="f0dbcbbcd22a7fd9a479ff68d4daa9225fb2f3b1"
PR="R3"
SRC_URI = "git://git.linphone.org/antlr3.git"
LIC_FILES_CHKSUM= "file://COPYING;md5=13c502aaa9b2ca91d01a3aae44d899b4"
DESCRIPTION = "SIP stack from Belledonne Communications"
LICENSE = "GPL"
DEPENDS_${PN} = "polarssl-dev antlr3c-dev"
DEPENDS = "polarssl-dev antlr3c-dev"
RDEPENDS_${PN} = "polarssl-dev antlr3c-dev"
EXTRA_OECONF += "--disable-strict --with-antlr=${STAGING_DIR_HOST}${layout_exec_prefix}/usr --with-polarssl=${STAGING_DIR_HOST}${layout_exec_prefix}/usr"
INSANE_SKIP_belle-sip += "dev-deps"
inherit autotools pkgconfig
do_autoreconf () {
./autogen.sh
}
require belle-sip.inc
SRCREV="af93922ac91cf3cbf5ceed0328bf43d08d37714e"
S = "${WORKDIR}/git"
PR="R1"
SRC_URI = "git://git.linphone.org/belle-sip.git;commit=${SRCREV}"
LIC_FILES_CHKSUM = "file://COPYING;md5=9f9938e31db89d55a796e86808c96848"
# We have a conf and classes directory, append to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have a recipes directory, add to BBFILES
BBFILES += "${LAYERDIR}/*.bb ${LAYERDIR}/*/*.bb"
BBFILE_COLLECTIONS += "linphone-layer"
BBFILE_PATTERN_linphone-layer := "^${LAYERDIR}/"
BBFILE_PRIORITY_linphone-layer = "50"
--- linphone/mediastreamer2/src/alsa.c_orig 2011-05-24 12:39:33.824600109 +0200
+++ linphone/mediastreamer2/src/alsa.c 2011-05-24 12:40:04.760407404 +0200
@@ -32,8 +32,8 @@
/*in case of troubles with a particular driver, try incrementing ALSA_PERIOD_SIZE
to 512, 1024, 2048, 4096...
then try incrementing the number of periods*/
-#define ALSA_PERIODS 8
-#define ALSA_PERIOD_SIZE 256
+#define ALSA_PERIODS 4
+#define ALSA_PERIOD_SIZE 512
/*uncomment the following line if you have problems with an alsa driver
having sound quality trouble:*/
diff -urNad libgsm-1.0.12~/Makefile libgsm-1.0.12/Makefile
--- libgsm-1.0.12~/Makefile 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.12/Makefile 2007-11-01 15:43:06.000000000 +0100
@@ -96,7 +96,7 @@
# Other tools
SHELL = /bin/sh
-LN = ln
+LN = ln -s
BASENAME = basename
AR = ar
ARFLAGS = cr
@@ -140,6 +140,7 @@
# Targets
LIBGSM = $(LIB)/libgsm.a
+LIBGSMSO= $(LIB)/libgsm.so
TOAST = $(BIN)/toast
UNTOAST = $(BIN)/untoast
@@ -279,7 +280,7 @@
# Target rules
-all: $(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST)
+all: $(LIBGSM) $(LIBGSMSO) $(TOAST) $(TCAT) $(UNTOAST)
@-echo $(ROOT): Done.
tst: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result
@@ -299,6 +300,11 @@
# The basic API: libgsm
+$(LIBGSMSO): $(LIB) $(GSM_OBJECTS)
+ $(LD) -o $@.1.0.12 -shared -Xlinker -soname -Xlinker libgsm.so.1 $(GSM_OBJECTS) -lc $(LDFLAGS)
+ ln -fs libgsm.so.1.0.12 lib/libgsm.so.1
+ ln -fs libgsm.so.1.0.12 lib/libgsm.so
+
$(LIBGSM): $(LIB) $(GSM_OBJECTS)
-rm $(RMFLAGS) $(LIBGSM)
$(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS)
@@ -308,15 +314,15 @@
# Toast, Untoast and Tcat -- the compress-like frontends to gsm.
$(TOAST): $(BIN) $(TOAST_OBJECTS) $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB)
+ $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSMSO) $(LDLIB)
$(UNTOAST): $(BIN) $(TOAST)
-rm $(RMFLAGS) $(UNTOAST)
- $(LN) $(TOAST) $(UNTOAST)
+ $(LN) toast $(UNTOAST)
$(TCAT): $(BIN) $(TOAST)
-rm $(RMFLAGS) $(TCAT)
- $(LN) $(TOAST) $(TCAT)
+ $(LN) toast $(TCAT)
# The local bin and lib directories
@@ -426,7 +432,9 @@
clean: semi-clean
-rm $(RMFLAGS) $(LIBGSM) $(ADDTST)/add \
- $(TOAST) $(TCAT) $(UNTOAST) \
+ $(LIBGSMSO) $(LIB)/libgsm.so.1.0.12 \
+ $(LIB)libgsm.so.1 \
+ $(TOAST) $(TCAT) $(UNTOAST) \
$(ROOT)/gsm-1.0.tar.Z
diff -urNad libgsm-1.0.10~/inc/gsm.h libgsm-1.0.10/inc/gsm.h
--- libgsm-1.0.10~/inc/gsm.h 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/inc/gsm.h 2007-11-01 15:44:52.000000000 +0100
@@ -54,6 +54,10 @@
#define GSM_OPT_FRAME_INDEX 5
#define GSM_OPT_FRAME_CHAIN 6
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern gsm gsm_create GSM_P((void));
extern void gsm_destroy GSM_P((gsm));
@@ -66,6 +70,10 @@
extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *));
extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *));
+#ifdef __cplusplus
+}
+#endif
+
#undef GSM_P
#endif /* GSM_H */
diff -urNad libgsm-1.0.10~/Makefile libgsm-1.0.10/Makefile
--- libgsm-1.0.10~/Makefile 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/Makefile 2007-11-01 15:48:02.000000000 +0100
@@ -151,7 +151,7 @@
HEADERS = $(INC)/proto.h \
$(INC)/unproto.h \
- $(INC)/config.h \
+ $(INC)/gsm_config.h \
$(INC)/private.h \
$(INC)/gsm.h \
$(INC)/toast.h \
diff -urNad libgsm-1.0.10~/inc/config.h libgsm-1.0.10/inc/config.h
--- libgsm-1.0.10~/inc/config.h 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/inc/config.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-/*efine SIGHANDLER_T int /* signal handlers are void */
-/*efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */
-
-#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
-#define HAS_LIMITS_H 1 /* /usr/include/limits.h */
-#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
-#define HAS_ERRNO_DECL 1 /* errno.h declares errno */
-
-#define HAS_FSTAT 1 /* fstat syscall */
-#define HAS_FCHMOD 1 /* fchmod syscall */
-#define HAS_CHMOD 1 /* chmod syscall */
-#define HAS_FCHOWN 1 /* fchown syscall */
-#define HAS_CHOWN 1 /* chown syscall */
-/*efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */
-
-#define HAS_STRING_H 1 /* /usr/include/string.h */
-/*efine HAS_STRINGS_H 1 /* /usr/include/strings.h */
-
-#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
-#define HAS_UTIME 1 /* POSIX utime(path, times) */
-/*efine HAS_UTIMES 1 /* use utimes() syscall instead */
-#define HAS_UTIME_H 1 /* UTIME header file */
-#define HAS_UTIMBUF 1 /* struct utimbuf */
-/*efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */
-
-#endif /* CONFIG_H */
diff -urNad libgsm-1.0.10~/inc/gsm_config.h libgsm-1.0.10/inc/gsm_config.h
--- libgsm-1.0.10~/inc/gsm_config.h 1970-01-01 01:00:00.000000000 +0100
+++ libgsm-1.0.10/inc/gsm_config.h 2007-11-01 15:46:19.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+/*efine SIGHANDLER_T int -* signal handlers are void */
+/*efine HAS_SYSV_SIGNAL 1 -* sigs not blocked/reset? */
+
+#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
+#define HAS_STDIO_H 1 /* /usr/include/stdio.h */
+/*efine HAS_LIMITS_H 1 -* /usr/include/limits.h */
+#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
+
+#define HAS_FSTAT 1 /* fstat syscall */
+#define HAS_FCHMOD 1 /* fchmod syscall */
+#define HAS_CHMOD 1 /* chmod syscall */
+#define HAS_FCHOWN 1 /* fchown syscall */
+#define HAS_CHOWN 1 /* chown syscall */
+/*efine HAS__FSETMODE 1 -* _fsetmode -- set file mode */
+
+#define HAS_STRING_H 1 /* /usr/include/string.h */
+/*efine HAS_STRINGS_H 1 -* /usr/include/strings.h */
+
+#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
+#define HAS_UTIME 1 /* POSIX utime(path, times) */
+/*efine HAS_UTIMES 1 -* use utimes() syscall instead */
+#define HAS_UTIME_H 1 /* UTIME header file */
+/*efine HAS_UTIMBUF 1 -* struct utimbuf */
+/*efine HAS_UTIMEUSEC 1 -* microseconds in utimbuf? */
+
+#endif /* CONFIG_H */
diff -urNad libgsm-1.0.10~/inc/toast.h libgsm-1.0.10/inc/toast.h
--- libgsm-1.0.10~/inc/toast.h 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/inc/toast.h 2007-11-01 15:48:17.000000000 +0100
@@ -9,7 +9,7 @@
#ifndef TOAST_H
#define TOAST_H /* Guard against multiple includes */
-#include "config.h"
+#include "gsm_config.h"
#include <sys/types.h>
#include <sys/stat.h>
diff -urNad libgsm-1.0.10~/src/code.c libgsm-1.0.10/src/code.c
--- libgsm-1.0.10~/src/code.c 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/src/code.c 2007-11-01 15:48:34.000000000 +0100
@@ -6,7 +6,7 @@
/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
-#include "config.h"
+#include "gsm_config.h"
#ifdef HAS_STDLIB_H
diff -urNad libgsm-1.0.10~/src/gsm_create.c libgsm-1.0.10/src/gsm_create.c
--- libgsm-1.0.10~/src/gsm_create.c 1996-07-02 16:32:44.000000000 +0200
+++ libgsm-1.0.10/src/gsm_create.c 2007-11-01 15:48:48.000000000 +0100
@@ -6,7 +6,7 @@
static char const ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $";
-#include "config.h"
+#include "gsm_config.h"
#ifdef HAS_STRING_H
#include <string.h>
diff -urNad libgsm-1.0.10~/src/gsm_destroy.c libgsm-1.0.10/src/gsm_destroy.c
--- libgsm-1.0.10~/src/gsm_destroy.c 1996-07-02 16:32:39.000000000 +0200
+++ libgsm-1.0.10/src/gsm_destroy.c 2007-11-01 15:48:57.000000000 +0100
@@ -7,7 +7,7 @@
/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */
#include "gsm.h"
-#include "config.h"
+#include "gsm_config.h"
#include "proto.h"
#ifdef HAS_STDLIB_H
diff -urNad libgsm-1.0.10~/tls/taste.c libgsm-1.0.10/tls/taste.c
--- libgsm-1.0.10~/tls/taste.c 1996-07-02 16:33:05.000000000 +0200
+++ libgsm-1.0.10/tls/taste.c 2007-11-01 15:49:54.000000000 +0100
@@ -10,7 +10,7 @@
#include <string.h>
#include <memory.h>
-#include "config.h"
+#include "gsm_config.h"
#ifdef HAS_STDLIB_H
# include <stdlib.h>
diff -urNad libgsm-1.0.10~/inc/toast.h libgsm-1.0.10/inc/toast.h
--- libgsm-1.0.10~/inc/toast.h 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/inc/toast.h 2007-11-01 15:52:33.000000000 +0100
@@ -16,11 +16,12 @@
#include <stdio.h>
#include <ctype.h>
+#include <pthread.h>
#include <signal.h>
#include <errno.h>
-#ifndef HAS_ERRNO_DECL
- extern int errno;
+#ifndef errno
+ extern int errno;
#endif
#ifdef HAS_LIMITS_H
@@ -37,6 +38,10 @@
# endif
#endif
+#ifdef HAS_STDIO_H
+# include <stdio.h>
+#endif
+
#include "gsm.h"
#ifndef S_ISREG
diff -urNad libgsm-1.0.10~/src/code.c libgsm-1.0.10/src/code.c
--- libgsm-1.0.10~/src/code.c 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/src/code.c 2007-11-01 15:52:33.000000000 +0100
@@ -9,8 +9,8 @@
#include "config.h"
-#ifdef HAS_STDLIB_H
-#include <stdlib.h>
+#ifdef HAS_STRING_H
+#include <string.h>
#else
# include "proto.h"
extern char * memcpy P((char *, char *, int));
diff -urNad libgsm-1.0.10~/src/debug.c libgsm-1.0.10/src/debug.c
--- libgsm-1.0.10~/src/debug.c 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/src/debug.c 2007-11-01 15:53:42.000000000 +0100
@@ -49,7 +49,7 @@
fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
while (from <= to) {
- fprintf(stderr, "%d ", ptr[ from ] );
+ fprintf(stderr, "%ld ", ptr[ from ] );
from++;
if (nprinted++ >= 7) {
nprinted = 0;
@@ -63,14 +63,14 @@
char * name,
longword value )
{
- fprintf(stderr, "%s: %d\n", name, (long)value );
+ fprintf(stderr, "%s: %ld\n", name, (long)value );
}
void gsm_debug_word P2( (name, value),
char * name,
word value )
{
- fprintf(stderr, "%s: %d\n", name, (long)value);
+ fprintf(stderr, "%s: %ld\n", name, (long)value);
}
#endif
diff -urNad libgsm-1.0.10~/src/toast.c libgsm-1.0.10/src/toast.c
--- libgsm-1.0.10~/src/toast.c 2007-11-01 15:37:52.000000000 +0100
+++ libgsm-1.0.10/src/toast.c 2007-11-01 15:53:42.000000000 +0100
@@ -251,8 +251,8 @@
{
char * s;
if (!(s = malloc(len))) {
- fprintf(stderr, "%s: failed to malloc %d bytes -- abort\n",
- progname, len);
+ fprintf(stderr, "%s: failed to malloc %ld bytes -- abort\n",
+ progname, (long) len);
onintr();
exit(1);
}
@@ -270,7 +270,7 @@
maxlen = strlen(name) + 1 + strlen(want) + strlen(cut);
p = strcpy(emalloc(maxlen), name);
- if (s = suffix(p, cut)) strcpy(s, want);
+ if ((s = suffix(p, cut))) strcpy(s, want);
else if (*want && !suffix(p, want)) strcat(p, want);
return p;
@@ -386,7 +386,7 @@
ut[0] = instat.st_atime;
ut[1] = instat.st_mtime;
- (void) utime(outname, ut);
+ (void) utime(outname, (struct utimbuf *)ut);
#endif /* UTIMBUF */
}
@@ -416,7 +416,7 @@
}
if (st->st_nlink > 1 && !f_cat && !f_precious) {
fprintf(stderr,
- "%s: \"%s\" has %s other link%s -- unchanged.\n",
+ "%s: \"%s\" has %d other link%s -- unchanged.\n",
progname,name,st->st_nlink - 1,"s" + (st->st_nlink<=2));