summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/client/client.c6
-rw-r--r--source3/client/clitar.c48
-rw-r--r--source3/configure.in18
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/safe_string.h19
-rw-r--r--source3/libsmb/cliconnect.c4
-rw-r--r--source3/libsmb/clifile.c2
-rw-r--r--source3/libsmb/clilist.c4
-rw-r--r--source3/nsswitch/winbindd_wins.c16
-rw-r--r--source3/smbd/negprot.c6
-rw-r--r--source3/smbd/reply.c2
-rw-r--r--source3/smbd/srvstr.c41
-rw-r--r--source3/utils/net.c2
-rw-r--r--source3/utils/net_rap.c4
-rw-r--r--source3/utils/pdbedit.c22
-rw-r--r--source3/utils/smbcacls.c2
17 files changed, 91 insertions, 108 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index a198298102..1084c17f08 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -322,7 +322,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
smbd/process.o smbd/service.o smbd/error.o \
- printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \
+ printing/printfsp.o lib/util_seaccess.o \
smbd/build_options.o \
smbd/change_trust_pw.o \
$(MANGLE_OBJ)
diff --git a/source3/client/client.c b/source3/client/client.c
index 20198fc5c8..1248c25659 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2349,7 +2349,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
char *sharename;
/* make a copy so we don't modify the global string 'service' */
- safe_strcpy(servicename, share, sizeof(servicename)-1);
+ fstrcpy(servicename, share);
sharename = servicename;
if (*sharename == '\\') {
server = sharename+2;
@@ -2624,9 +2624,9 @@ static int do_message_op(void)
make_nmb_name(&calling, global_myname(), 0x0);
make_nmb_name(&called , desthost, name_type);
- safe_strcpy(server_name, desthost, sizeof(server_name));
+ fstrcpy(server_name, desthost);
snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
- safe_strcat(server_name, name_type_hex, sizeof(server_name));
+ fstrcat(server_name, name_type_hex);
zero_ip(&ip);
if (have_ip) ip = dest_ip;
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index 612a383ce0..579110f75f 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -202,7 +202,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
/* write out a "standard" tar format header */
hb.dbuf.name[NAMSIZ-1]='\0';
- safe_strcpy(hb.dbuf.mode, amode, strlen(amode));
+ safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
@@ -796,11 +796,11 @@ static void do_tar(file_info *finfo)
DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
- safe_strcpy(exclaim, cur_dir, sizeof(pstring));
+ pstrcpy(exclaim, cur_dir);
*(exclaim+strlen(exclaim)-1)='\0';
- safe_strcat(exclaim, "\\", sizeof(pstring));
- safe_strcat(exclaim, finfo->name, sizeof(exclaim));
+ pstrcat(exclaim, "\\");
+ pstrcat(exclaim, finfo->name);
DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
@@ -820,12 +820,12 @@ static void do_tar(file_info *finfo)
pstring saved_curdir;
pstring mtar_mask;
- safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
+ pstrcpy(saved_curdir, cur_dir);
DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
- safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
- safe_strcat(cur_dir,"\\", sizeof(cur_dir));
+ pstrcat(cur_dir,finfo->name);
+ pstrcat(cur_dir,"\\");
DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
@@ -836,16 +836,16 @@ static void do_tar(file_info *finfo)
DEBUG(0,(" directory %s\n", cur_dir));
}
ntarf++; /* Make sure we have a file on there */
- safe_strcpy(mtar_mask,cur_dir, sizeof(pstring));
- safe_strcat(mtar_mask,"*", sizeof(pstring));
+ pstrcpy(mtar_mask,cur_dir);
+ pstrcat(mtar_mask,"*");
DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
do_list(mtar_mask, attribute, do_tar, False, True);
- safe_strcpy(cur_dir,saved_curdir, sizeof(pstring));
+ pstrcpy(cur_dir,saved_curdir);
}
else
{
- safe_strcpy(rname,cur_dir, sizeof(pstring));
- safe_strcat(rname,finfo->name, sizeof(pstring));
+ pstrcpy(rname,cur_dir);
+ pstrcat(rname,finfo->name);
do_atar(rname,finfo->name,finfo);
}
}
@@ -1362,8 +1362,8 @@ int cmd_setmode(void)
return 1;
}
- safe_strcpy(fname, cur_dir, sizeof(pstring));
- safe_strcat(fname, buf, sizeof(pstring));
+ pstrcpy(fname, cur_dir);
+ pstrcat(fname, buf);
while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
q=buf;
@@ -1459,32 +1459,32 @@ int process_tar(void)
if (strrchr_m(cliplist[i], '\\')) {
pstring saved_dir;
- safe_strcpy(saved_dir, cur_dir, sizeof(pstring));
+ pstrcpy(saved_dir, cur_dir);
if (*cliplist[i]=='\\') {
- safe_strcpy(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cliplist[i]);
} else {
- safe_strcpy(tarmac, cur_dir, sizeof(pstring));
- safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
}
- safe_strcpy(cur_dir, tarmac, sizeof(pstring));
+ pstrcpy(cur_dir, tarmac);
*(strrchr_m(cur_dir, '\\')+1)='\0';
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
- safe_strcpy(cur_dir,saved_dir, sizeof(pstring));
+ pstrcpy(cur_dir,saved_dir);
} else {
- safe_strcpy(tarmac, cur_dir, sizeof(pstring));
- safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
}
}
} else {
pstring mask;
- safe_strcpy(mask,cur_dir, sizeof(pstring));
+ pstrcpy(mask,cur_dir);
DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
- safe_strcat(mask,"\\*", sizeof(pstring));
+ pstrcat(mask,"\\*");
do_list(mask,attribute,do_tar,False, True);
}
diff --git a/source3/configure.in b/source3/configure.in
index 69c001f59b..bc86473428 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -657,6 +657,24 @@ if test x"$samba_cv_immediate_structures" = x"yes"; then
fi
############################################
+# check if the compiler can do immediate structures
+AC_CACHE_CHECK([if the compiler will optimize out function calls],samba_cv_optimize_out_funcation_calls, [
+ AC_TRY_LINK([
+#include <stdio.h>],
+[
+ if (0) {
+ this_function_does_not_exist();
+ } else {
+ return 1;
+ }
+
+],
+ samba_cv_optimize_out_funcation_calls=yes,samba_cv_optimize_out_funcation_calls=no)])
+if test x"$samba_cv_optimize_out_funcation_calls" = x"yes"; then
+ AC_DEFINE(HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS,1,[Whether the compiler will optimize out function calls])
+fi
+
+############################################
# check for unix domain sockets
AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [
AC_TRY_COMPILE([
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 774df34de0..bdd8661f6f 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -832,6 +832,7 @@ struct printjob;
/* String routines */
+#include "srvstr.h"
#include "safe_string.h"
#ifdef __COMPAR_FN_T
diff --git a/source3/include/safe_string.h b/source3/include/safe_string.h
index ad7b4139a3..61ef4bdf96 100644
--- a/source3/include/safe_string.h
+++ b/source3/include/safe_string.h
@@ -129,11 +129,17 @@ size_t __unsafe_string_function_usage_here_char__(void);
safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
-/* inside the _fn varients of these is a call to 'clobber_region' - which might
- destory the stack on a buggy function. Help the debugging process by putting
- the function and line it was last called from into a static buffer
-
- But only for developers */
+/* Inside the _fn variants of these is a call to clobber_region(), -
+ * which might destroy the stack on a buggy function. We help the
+ * debugging process by putting the function and line who last caused
+ * a clobbering into a static buffer. If the program crashes at
+ * address 0xf1f1f1f1 then this function is probably, but not
+ * necessarily, to blame. */
+
+/* overmalloc_safe_strcpy: DEPRECATED! Used when you know the
+ * destination buffer is longer than maxlength, but you don't know how
+ * long. This is not a good situation, because we can't do the normal
+ * sanity checks. Don't use in new code! */
#ifdef DEVELOPER
#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(__FUNCTION__,__LINE__,dest,src,maxlength)
@@ -214,7 +220,4 @@ size_t __unsafe_string_function_usage_here_char__(void);
#define strlower(s) strlower_m(s)
#define strupper(s) strupper_m(s)
-#define safe_strcpy_base(dest, src, base, size) \
- safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
-
#endif
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 49b0004ac2..54a282e805 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -66,7 +66,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
memcpy(pword, pass, passlen);
} else if (passlen > 0) {
/* Plaintext mode needed, assume plaintext supplied. */
- passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
+ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
}
/* send a session setup command */
@@ -774,7 +774,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
/*
* Non-encrypted passwords - convert to DOS codepage before using.
*/
- passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
+ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
} else {
memcpy(pword, pass, passlen);
}
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 8e84963c09..d86f36405d 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -948,7 +948,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path)
pstring path2;
char *p;
- safe_strcpy(path2,path,sizeof(pstring));
+ pstrcpy(path2,path);
trim_string(path2,NULL,"\\");
if (!*path2) *path2 = '\\';
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 3884e4da82..5bd1283ab7 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,6,info_level);
SIVAL(param,8,0);
p = param+12;
- p += clistr_push(cli, param+12, mask, -1,
+ p += clistr_push(cli, param+12, mask, sizeof(param)-12,
STR_TERMINATE);
} else {
setup = TRANSACT2_FINDNEXT;
@@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SIVAL(param,6,0); /* ff_resume_key */
SSVAL(param,10,8+4+2); /* continue + resume required + close on end */
p = param+12;
- p += clistr_push(cli, param+12, mask, -1,
+ p += clistr_push(cli, param+12, mask, sizeof(param)-12,
STR_TERMINATE);
}
diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c
index 8ddd5dc10d..a1d38ed69a 100644
--- a/source3/nsswitch/winbindd_wins.c
+++ b/source3/nsswitch/winbindd_wins.c
@@ -137,8 +137,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
- safe_strcat(response,state->request.data.winsreq,maxlen);
- safe_strcat(response,"\t",maxlen);
+ fstrcat(response,state->request.data.winsreq);
+ fstrcat(response,"\t");
for (i = 0; i < count; i++) {
/* ignore group names */
if (status[i].flags & 0x80) continue;
@@ -148,8 +148,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
- safe_strcat(response, status[i].name, maxlen);
- safe_strcat(response, " ", maxlen);
+ fstrcat(response, status[i].name);
+ fstrcat(response, " ");
}
}
/* make last character a newline */
@@ -190,16 +190,16 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
/* Clear out the newline character */
response[strlen(response)-1] = ' ';
}
- safe_strcat(response,addr,maxlen);
- safe_strcat(response,"\t",maxlen);
+ fstrcat(response,addr);
+ fstrcat(response,"\t");
}
size = strlen(state->request.data.winsreq) + strlen(response);
if (size > maxlen) {
SAFE_FREE(ip_list);
return WINBINDD_ERROR;
}
- safe_strcat(response,state->request.data.winsreq,maxlen);
- safe_strcat(response,"\n",maxlen);
+ fstrcat(response,state->request.data.winsreq);
+ fstrcat(response,"\n");
SAFE_FREE(ip_list);
} else
return WINBINDD_ERROR;
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index c8f023514e..db0694a840 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -167,7 +167,7 @@ static int reply_lanman2(char *inbuf, char *outbuf)
static int negprot_spnego(char *p)
{
DATA_BLOB blob;
- uint8 guid[16];
+ uint8 guid[17];
const char *OIDs_krb5[] = {OID_KERBEROS5,
OID_KERBEROS5_OLD,
OID_NTLMSSP,
@@ -178,8 +178,8 @@ static int negprot_spnego(char *p)
global_spnego_negotiated = True;
- memset(guid, 0, 16);
- safe_strcpy((char *)guid, global_myname(), 16);
+ ZERO_STRUCT(guid);
+ safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1);
strlower((char *)guid);
#if 0
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index a738baa9ff..775b617df5 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -161,7 +161,7 @@ int reply_tcon(connection_struct *conn,
*service_buf = *password = *dev = 0;
p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
p += pwlen;
p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
diff --git a/source3/smbd/srvstr.c b/source3/smbd/srvstr.c
deleted file mode 100644
index 36fecf5bd2..0000000000
--- a/source3/smbd/srvstr.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- server specific string routines
- Copyright (C) Andrew Tridgell 2001
-
- 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 "includes.h"
-
-int srvstr_push(void *base_ptr, void *dest, const char *src, int dest_len, int flags)
-{
- return push_string(base_ptr, dest, src, dest_len, flags);
-}
-
-int srvstr_pull(void *base_ptr, char *dest, const void *src, int dest_len, int src_len,
- int flags)
-{
- return pull_string(base_ptr, dest, src, dest_len, src_len, flags);
-}
-
-/* pull a string from the smb_buf part of a packet. In this case the
- string can either be null terminated or it can be terminated by the
- end of the smbbuf area
-*/
-int srvstr_pull_buf(void *inbuf, char *dest, const void *src, int dest_len, int flags)
-{
- return pull_string(inbuf, dest, src, dest_len, smb_bufrem(inbuf, src), flags);
-}
diff --git a/source3/utils/net.c b/source3/utils/net.c
index ada0ed53e1..7588771fbc 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -241,7 +241,7 @@ BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *dom
if (!lookup_dc_name(global_myname(), domain_name, server_ip, dc_name))
return False;
- safe_strcpy(server_name, dc_name, FSTRING_LEN);
+ fstrcpy(server_name, dc_name);
return True;
} else
return False;
diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c
index 8f3dd53fa6..f52eabf494 100644
--- a/source3/utils/net_rap.c
+++ b/source3/utils/net_rap.c
@@ -638,7 +638,7 @@ static int rap_user_add(int argc, const char **argv)
if (!(cli = net_make_ipc_connection(0)))
return -1;
- safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name));
+ safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name)-1);
if (opt_flags == -1)
opt_flags = 0x21;
@@ -755,7 +755,7 @@ static int rap_group_add(int argc, const char **argv)
return -1;
/* BB check for length 21 or smaller explicitly ? BB */
- safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name));
+ safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
grinfo.reserved1 = '\0';
grinfo.comment = smb_xstrdup(opt_comment);
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index 9df10c21a4..265bda1e5d 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -363,20 +363,21 @@ static int new_machine (struct pdb_context *in, const char *machine_in)
{
SAM_ACCOUNT *sam_pwent=NULL;
fstring machinename;
+ fstring machineaccount;
struct passwd *pwd = NULL;
- char name[16];
fstrcpy(machinename, machine_in);
+ machinename[15]= '\0';
if (machinename[strlen (machinename) -1] == '$')
machinename[strlen (machinename) -1] = '\0';
strlower_m(machinename);
- safe_strcpy (name, machinename, 16);
- safe_strcat (name, "$", 16);
+ fstrcpy(machineaccount, machinename);
+ fstrcat(machineaccount, "$");
- if ((pwd = getpwnam_alloc(name))) {
+ if ((pwd = getpwnam_alloc(machineaccount))) {
if (!NT_STATUS_IS_OK(pdb_init_sam_pw( &sam_pwent, pwd))) {
fprintf(stderr, "Could not init sam from pw\n");
passwd_free(&pwd);
@@ -392,14 +393,14 @@ static int new_machine (struct pdb_context *in, const char *machine_in)
pdb_set_plaintext_passwd (sam_pwent, machinename);
- pdb_set_username (sam_pwent, name, PDB_CHANGED);
+ pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED);
pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED);
pdb_set_group_sid_from_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS, PDB_CHANGED);
if (NT_STATUS_IS_OK(in->pdb_add_sam_account (in, sam_pwent))) {
- print_user_info (in, name, True, False);
+ print_user_info (in, machineaccount, True, False);
} else {
fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
pdb_free_sam (&sam_pwent);
@@ -435,12 +436,13 @@ static int delete_user_entry (struct pdb_context *in, const char *username)
static int delete_machine_entry (struct pdb_context *in, const char *machinename)
{
- char name[16];
+ fstring name;
SAM_ACCOUNT *samaccount = NULL;
- safe_strcpy (name, machinename, 16);
- if (name[strlen(name)] != '$')
- safe_strcat (name, "$", 16);
+ fstrcpy(name, machinename);
+ name[15] = '\0';
+ if (name[strlen(name)-1] != '$')
+ fstrcat (name, "$");
if (!NT_STATUS_IS_OK(pdb_init_sam (&samaccount))) {
return -1;
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index a5cee0dae1..bce64df960 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -916,7 +916,7 @@ You can string acls together with spaces, commas or newlines\n\
if (filename[0] != '\\') {
pstring s;
s[0] = '\\';
- safe_strcpy(&s[1], filename, sizeof(pstring)-1);
+ safe_strcpy(&s[1], filename, sizeof(pstring)-2);
pstrcpy(filename, s);
}