diff --git a/Makefile b/Makefile index 90a0e8d..62e6827 100755 --- a/Makefile +++ b/Makefile @@ -36,8 +36,8 @@ TOBJS=testpri.o T2OBJS=testprilib.o STATIC_LIBRARY=libpri.a DYNAMIC_LIBRARY=libpri.so.1.0 -STATIC_OBJS=pri.o q921.o prisched.o q931.o pri_facility.o -DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo pri_facility.lo +STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o +DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS) INSTALL_PREFIX= INSTALL_BASE=/usr diff --git a/copy_string.c b/copy_string.c new file mode 100755 index 0000000..2bb0019 --- /dev/null +++ b/copy_string.c @@ -0,0 +1,41 @@ +/* + * libpri: An implementation of Primary Rate ISDN + * + * Written by Mark Spencer + * + * Copyright (C) 2005, Digium + * All Rights Reserved. + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include + +#include "libpri.h" +#include "pri_internal.h" + +void libpri_copy_string(char *dst, const char *src, size_t size) +{ + while (*src && size) { + *dst++ = *src++; + size--; + } + if (__builtin_expect(!size, 0)) + dst--; + *dst = '\0'; +} diff --git a/pri.c b/pri.c index 6c37c56..0493dac 100755 --- a/pri.c +++ b/pri.c @@ -1,13 +1,25 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * This program is confidential - * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * */ #include @@ -352,7 +364,7 @@ pri_event *pri_mkerror(struct pri *pri, char *errstr) { /* Return a configuration error */ pri->ev.err.e = PRI_EVENT_CONFIG_ERR; - strncpy(pri->ev.err.err, errstr, sizeof(pri->ev.err.err) - 1); + libpri_copy_string(pri->ev.err.err, errstr, sizeof(pri->ev.err.err)); return &pri->ev; } diff --git a/pri_facility.c b/pri_facility.c index 478f457..b6c4b56 100755 --- a/pri_facility.c +++ b/pri_facility.c @@ -1,13 +1,26 @@ -/* - This file and it's contents are licensed under the terms and conditions - of the GNU Public License. See http://www.gnu.org for details. - - Routines for dealing with facility messages and their respective - components (ROSE) - - by Matthew Fredrickson - Copyright (C) 2004-2005 Digium, Inc -*/ +/* + * libpri: An implementation of Primary Rate ISDN + * + * Written by Matthew Fredrickson + * + * Copyright (C) 2004-2005, Digium + * All Rights Reserved. + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ #include "compat.h" #include "libpri.h" @@ -501,23 +514,15 @@ static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *ca call->redirectingplan = divertingnr.npi; call->redirectingpres = divertingnr.pres; call->redirectingreason = diversion_reason; - strncpy(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum)-1); - call->redirectingnum[sizeof(call->redirectingnum)-1] = '\0'; + libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum)); } if (originalcallednr.pres >= 0) { call->origcalledplan = originalcallednr.npi; call->origcalledpres = originalcallednr.pres; - strncpy(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)-1); - call->origcallednum[sizeof(call->origcallednum)-1] = '\0'; - } - if (strlen(redirectingname) > 0) { - strncpy(call->redirectingname, redirectingname, sizeof(call->redirectingname)); - call->redirectingname[sizeof(call->redirectingname)-1] = '\0'; - } - if (strlen(origcalledname) > 0) { - strncpy(call->origcalledname, origcalledname, sizeof(call->origcalledname)); - call->origcalledname[sizeof(call->origcalledname)-1] = '\0'; + libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)); } + libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname)); + libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname)); return 0; } while (0); diff --git a/pri_internal.h b/pri_internal.h index 86ef495..0f58a45 100755 --- a/pri_internal.h +++ b/pri_internal.h @@ -251,4 +251,6 @@ extern void pri_message(struct pri *pri, char *fmt, ...); extern void pri_error(struct pri *pri, char *fmt, ...); +void libpri_copy_string(char *dst, const char *src, size_t size); + #endif diff --git a/pridump.c b/pridump.c index c1c46d3..3868fdc 100755 --- a/pridump.c +++ b/pridump.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/prisched.c b/prisched.c index d414ece..eee5f1c 100755 --- a/prisched.c +++ b/prisched.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify @@ -22,9 +22,10 @@ * */ +#include + #include "libpri.h" #include "pri_internal.h" -#include static int maxsched = 0; diff --git a/pritest.c b/pritest.c index aa68af3..7f7d32e 100755 --- a/pritest.c +++ b/pritest.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/q921.c b/q921.c index bde095a..cef97f2 100755 --- a/q921.c +++ b/q921.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify @@ -21,7 +21,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + #include #include #include diff --git a/q931.c b/q931.c index f41d3cc..7383b21 100755 --- a/q931.c +++ b/q931.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify @@ -21,7 +21,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + #include "compat.h" #include "libpri.h" #include "pri_internal.h" @@ -938,7 +938,7 @@ static FUNC_RECV(receive_calling_party_number) * Copy ANI to Caller*ID if Caller*ID is not already set */ if (!*call->callernum) - strncpy(call->callernum, call->callerani, sizeof(call->callernum) - 1); + libpri_copy_string(call->callernum, call->callerani, sizeof(call->callernum)); } else q931_get_number((u_int8_t *)call->callernum, sizeof(call->callernum), data, length); @@ -1524,31 +1524,28 @@ static FUNC_DUMP(dump_time_date) static FUNC_DUMP(dump_keypad_facility) { - char tmp[64] = ""; + char tmp[64]; if (ie->len == 0 || ie->len > sizeof(tmp)) return; - strncpy(tmp, (char *) ie->data, sizeof(tmp)); + libpri_copy_string(tmp, (char *) ie->data, sizeof(tmp)); pri_message(pri, "%c Keypad Facility (len=%2d) [ %s ]\n", prefix, ie->len, tmp ); } static FUNC_RECV(receive_keypad_facility) { - int mylen = 0; + int mylen; if (ie->len == 0) return -1; if (ie->len > sizeof(call->digitbuf)) - mylen = sizeof(call->digitbuf) - 1; + mylen = sizeof(call->digitbuf); else mylen = ie->len; - strncpy(call->digitbuf, (char *) ie->data, mylen); - - /* I must be really neurotic */ - call->digitbuf[sizeof(call->digitbuf)-1] = '\0'; + libpri_copy_string(call->digitbuf, (char *) ie->data, mylen); return 0; } @@ -1557,7 +1554,7 @@ static FUNC_DUMP(dump_display) { int x, y; char *buf = malloc(len + 1); - char tmp[80]=""; + char tmp[80]; if (buf) { x=y=0; if ((x < ie->len) && (ie->data[x] & 0x80)) { @@ -2908,12 +2905,12 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) else if (c->channelno) c->chanflags = FLAG_PREFERRED; if (req->caller) { - strncpy(c->callernum, req->caller, sizeof(c->callernum) - 1); + libpri_copy_string(c->callernum, req->caller, sizeof(c->callernum)); c->callerplan = req->callerplan; if (req->callername) - strncpy(c->callername, req->callername, sizeof(c->callername) - 1); + libpri_copy_string(c->callername, req->callername, sizeof(c->callername)); else - strcpy(c->callername, ""); + c->callername[0] = '\0'; if ((pri->switchtype == PRI_SWITCH_DMS100) || (pri->switchtype == PRI_SWITCH_ATT4ESS)) { /* Doesn't like certain presentation types */ @@ -2922,13 +2919,13 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) } c->callerpres = req->callerpres; } else { - strcpy(c->callernum, ""); - strcpy(c->callername, ""); + c->callernum[0] = '\0'; + c->callername[0] = '\0'; c->callerplan = PRI_UNKNOWN; c->callerpres = PRES_NUMBER_NOT_AVAILABLE; } if (req->redirectingnum) { - strncpy(c->redirectingnum, req->redirectingnum, sizeof(c->redirectingnum) - 1); + libpri_copy_string(c->redirectingnum, req->redirectingnum, sizeof(c->redirectingnum)); c->redirectingplan = req->redirectingplan; if ((pri->switchtype == PRI_SWITCH_DMS100) || (pri->switchtype == PRI_SWITCH_ATT4ESS)) { @@ -2939,13 +2936,13 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) c->redirectingpres = req->redirectingpres; c->redirectingreason = req->redirectingreason; } else { - strcpy(c->redirectingnum, ""); + c->redirectingnum[0] = '\0'; c->redirectingplan = PRI_UNKNOWN; c->redirectingpres = PRES_NUMBER_NOT_AVAILABLE; c->redirectingreason = PRI_REDIR_UNKNOWN; } if (req->called) { - strncpy(c->callednum, req->called, sizeof(c->callednum) - 1); + libpri_copy_string(c->callednum, req->called, sizeof(c->callednum)); c->calledplan = req->calledplan; } else return -1; @@ -3148,7 +3145,7 @@ int q931_receive(struct pri *pri, q931_h *h, int len) c->ri = -1; break; case Q931_FACILITY: - strcpy(c->callername, ""); + c->callername[0] = '\0'; break; case Q931_SETUP: if (pri->debug & PRI_DEBUG_Q931_STATE) @@ -3168,21 +3165,21 @@ int q931_receive(struct pri *pri, q931_h *h, int len) c->calledplan = -1; c->callerplan = -1; c->callerpres = -1; - strcpy(c->callernum, ""); - strcpy(c->callednum, ""); - strcpy(c->callername, ""); + c->callernum[0] = '\0'; + c->callednum[0] = '\0'; + c->callername[0] = '\0'; c->redirectingplan = -1; c->redirectingpres = -1; c->redirectingreason = -1; c->origcalledplan = -1; c->origcalledpres = -1; c->origredirectingreason = -1; - strcpy(c->redirectingnum, ""); - strcpy(c->origcallednum, ""); - strcpy(c->redirectingname, ""); - strcpy(c->origcalledname, ""); + c->redirectingnum[0] = '\0'; + c->origcallednum[0] = '\0'; + c->redirectingname[0] = '\0'; + c->origcalledname[0] = '\0'; c->useruserprotocoldisc = -1; - strcpy(c->useruserinfo, ""); + c->useruserinfo[0] = '\0'; c->complete = 0; c->nonisdn = 0; /* Fall through */ @@ -3381,17 +3378,17 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.ring.callingpres = c->callerpres; pri->ev.ring.callingplan = c->callerplan; pri->ev.ring.ani2 = c->ani2; - strncpy(pri->ev.ring.callingani, c->callerani, sizeof(pri->ev.ring.callingani) - 1); - strncpy(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum) - 1); - strncpy(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname) - 1); + libpri_copy_string(pri->ev.ring.callingani, c->callerani, sizeof(pri->ev.ring.callingani)); + libpri_copy_string(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum)); + libpri_copy_string(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname)); pri->ev.ring.calledplan = c->calledplan; - strncpy(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr) - 1); - strncpy(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum) - 1); - strncpy(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname) - 1); - strncpy(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum) - 1); - strncpy(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum) - 1); - strncpy(pri->ev.ring.redirectingname, c->redirectingname, sizeof(pri->ev.ring.redirectingname) - 1); - strncpy(pri->ev.ring.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo) - 1); + libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); + libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum)); + libpri_copy_string(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname)); + libpri_copy_string(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum)); + libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum)); + libpri_copy_string(pri->ev.ring.redirectingname, c->redirectingname, sizeof(pri->ev.ring.redirectingname)); + libpri_copy_string(pri->ev.ring.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); pri->ev.ring.redirectingreason = c->redirectingreason; pri->ev.ring.origredirectingreason = c->origredirectingreason; pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE); @@ -3447,8 +3444,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len) break; } pri->ev.e = PRI_EVENT_FACNAME; - strncpy(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname) - 1); - strncpy(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingnum) - 1); + libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname)); + libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingnum)); pri->ev.facname.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); pri->ev.facname.cref = c->cr; pri->ev.facname.call = c; @@ -3630,14 +3627,14 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.e = PRI_EVENT_KEYPAD_DIGIT; pri->ev.digit.call = c; pri->ev.digit.channel = c->channelno | (c->ds1no << 8); - strncpy(pri->ev.digit.digits, c->digitbuf, sizeof(pri->ev.digit.digits)); + libpri_copy_string(pri->ev.digit.digits, c->digitbuf, sizeof(pri->ev.digit.digits)); return Q931_RES_HAVEEVENT; } pri->ev.e = PRI_EVENT_INFO_RECEIVED; pri->ev.ring.call = c; pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); - strncpy(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum) - 1); - strncpy(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr) - 1); + libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum)); + libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); pri->ev.ring.complete = c->complete; /* this covers IE 33 (Sending Complete) */ return Q931_RES_HAVEEVENT; case Q931_STATUS_ENQUIRY: diff --git a/testprilib.c b/testprilib.c index fbd8694..441ba6f 100755 --- a/testprilib.c +++ b/testprilib.c @@ -1,9 +1,9 @@ /* * libpri: An implementation of Primary Rate ISDN * - * Written by Mark Spencer + * Written by Mark Spencer * - * Copyright (C) 2001, Linux Support Services, Inc. + * Copyright (C) 2001-2005, Digium * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify