473,796 Members | 2,618 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strncpy help (long)

Hi, I am in the progress of writing a program that will read in the
contents of a directory and then do some stuff to some of the files. So
far I am getting the contents of the directory but I get a strange
result from one file. Here is my program, feel free to critique:

#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
void main(int argc, char *argv[])
{
int i;
int j;
int array_size;
DIR *dirp;
struct dirent *direntp;
char filename[NAME_MAX];

/* print usage */
switch(argc) {
case 1:
printf("Usage: %s path\n\n", argv[0]);
exit(1);
break;
/* print out dir contents */
default :
for ( i=1; i < argc; i++){
dirp = opendir( argv[i] );
printf("This is the dir %s.\n\n", argv[i]);
while ( (direntp = readdir( dirp )) != NULL )
{
printf( "1. strlen from raw {%d}\n", strlen(direntp->d_name) );
printf( "2. raw from pointer {%s}\n",direntp->d_name );
strncpy(filenam e,direntp->d_name,strlen( direntp->d_name));
array_size=strl en(filename);
printf("This is the string length %d\n", array_size);
if ( strncmp( filename, "r",1 )==0 ){
printf( "3. Modified string {%s}\n",filenam e );
}
for ( j=1; j <= array_size; j++ ) {
filename[j]=0;
}
}
}
break;
}

closedir( dirp );
exit(0);
}
I call the program:
myprog /usr/data/r*

I get data like this:
This is the dir /usr/data/rui19.

1. strlen from raw {1}
2. raw from pointer {.}
This is the string length 6
1. strlen from raw {2}
2. raw from pointer {..}
This is the string length 2
1. strlen from raw {14}
2. raw from pointer {rui19.ils.0001 }
This is the string length 14
3. Modified string {rui19.ils.0001 }

However one file gives me this:

1. strlen from raw {18}
2. raw from pointer {rui22.ils.0052 .bak}
This is the string length 22
3. Modified string {rui22.ils.0052 .baM-@M-^?^C}

What is that on the end of the file name? This file was created from a
winder's version of edt, vms guy just won't let go, and saved over a
Samba share to a Tru64 box. I don't know if some characters were
concatenated to the end of the filename, but an ls shows the filename
properly. Is there something in the filename or is my program to blame?
I have not tried removing or renaming the file as I don't want to lose
this behaviour until I undestand it. The odd part is that if I print
out the name directly from the dirent struct I don't see a problem, I
only see it after the strncpy. This is the only file that does this.

Also, I created the array_size variable because this wouldn't work.
What is wrong with this statement?

for ( j=1; j <= strlen(filename ); j++

Thanks!

fyb
--
This is my sig
Nov 14 '05 #1
9 2038
"fybar" <fy***@aristotl e.hammerdog.org > wrote > Hi, I am in the progress of writing a program that will read in the contents of a directory and then do some stuff to some of the files. So
far I am getting the contents of the directory but I get a strange
result from one file. Here is my program, feel free to critique:

#include <sys/types.h>
#include <dirent.h>

[snip]

I don't believe that these are header files that are kosher around here. I
wouldn't know unix from a boomerang (haven't used either). Maybe other
people can point you in the right direction. MPJ
Nov 14 '05 #2
In article <sl************ ******@aristotl e.hammerdog.org >,
fy***@aristotle .hammerdog.org (fybar) wrote:
What is that on the end of the file name? This file was created from a
winder's version of edt, vms guy just won't let go, and saved over a
Samba share to a Tru64 box. I don't know if some characters were
concatenated to the end of the filename, but an ls shows the filename
properly. Is there something in the filename or is my program to blame?
I have not tried removing or renaming the file as I don't want to lose
this behaviour until I undestand it. The odd part is that if I print
out the name directly from the dirent struct I don't see a problem, I
only see it after the strncpy. This is the only file that does this.


You don't want strncpy() -- you want strcpy(). strncpy() does not
'\0'-terminate the string if it's third argument is <= the length of
the second argument. You've carefully made sure that it is ==.

- jonathan
Nov 14 '05 #3

"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...
<snip>
You don't want strncpy() -- you want strcpy(). strncpy() does not
'\0'-terminate the string if it's third argument is <= the length of
the second argument. You've carefully made sure that it is ==.


In that case strcpy will cause a buffer-overrun and allow hostile code to be
executed. I'd suggest using strncpy and checking the results.
Nov 14 '05 #4
In article <41************ *********@dread er17.news.xs4al l.nl>,
"dandelion" <da*******@mead ow.net> wrote:
"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...
<snip>
You don't want strncpy() -- you want strcpy(). strncpy() does not
'\0'-terminate the string if it's third argument is <= the length of
the second argument. You've carefully made sure that it is ==.


In that case strcpy will cause a buffer-overrun and allow hostile code to be
executed. I'd suggest using strncpy and checking the results.


His use of strncpy() is wrong, and checking the results would not help
him:

....
char filename[NAME_MAX];
....
strncpy(filenam e,direntp->d_name,strlen( direntp->d_name));
....

It is just as susceptible to buffer overflows as strcpy() would be.
What the OP actually wants is strlcpy():

char filename[NAME_MAX];
....
if (strlcpy(filena me, direntp->d_name, sizeof (filename)) >=
sizeof(filename )) {
/* overflow */
}
....

size_t
strlcpy(char *out, const char *in, size_t len)
{
size_t ret = strlen(in);

if (ret < len) {
(void) strcpy(out, in);
} else {
(void) strncpy(out, in, len - 1);
out[len - 1] = '\0';
}
return (ret);
}

(yes, there are more efficient ways of writing strlcpy())

Cheers,
- jonathan
Nov 14 '05 #5

"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...
In article <41************ *********@dread er17.news.xs4al l.nl>,
"dandelion" <da*******@mead ow.net> wrote:
"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...
<snip>
You don't want strncpy() -- you want strcpy(). strncpy() does not
'\0'-terminate the string if it's third argument is <= the length of
the second argument. You've carefully made sure that it is ==.
In that case strcpy will cause a buffer-overrun and allow hostile code to be executed. I'd suggest using strncpy and checking the results.


His use of strncpy() is wrong, and checking the results would not help
him:

...

Ok. I checked and you're right.

char filename[NAME_MAX];
...
strncpy(filenam e,direntp->d_name,strlen( direntp->d_name));

strncpy(filenam e, direntp->d_name, NAME_MAX);

And check the results.

<snip>
(yes, there are more efficient ways of writing strlcpy())


I'm glad you noticed.

In fact, there aren't many sensible ways to implement it less efficient
without deliberately trying.

Cheers,

dandelion.

Nov 14 '05 #6

"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...

<snip>
size_t
strlcpy(char *out, const char *in, size_t len)
{
size_t ret = strlen(in);

if (ret < len) {
(void) strcpy(out, in);
} else {
(void) strncpy(out, in, len - 1);
out[len - 1] = '\0';
}
return (ret);
}

(yes, there are more efficient ways of writing strlcpy())


size_t
strlcpy(char *dst, const char *src, size_t len)
{
size_t cnt = 0;
len--;

while('\0' != src[cnt] && cnt < len)
{
dst[cnt] = src[cnt];
cnt++;
}

out[cnt] = '\0';
return cnt;
}

Cheers,
dandelion.

PS. The above is not tested and may contain errors.
Nov 14 '05 #7
In article <41************ ***********@dre ader15.news.xs4 all.nl>,
"dandelion" <da*******@mead ow.net> wrote:
"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...

<snip>
size_t
strlcpy(char *out, const char *in, size_t len)
{
size_t ret = strlen(in);

if (ret < len) {
(void) strcpy(out, in);
} else {
(void) strncpy(out, in, len - 1);
out[len - 1] = '\0';
}
return (ret);
}

(yes, there are more efficient ways of writing strlcpy())


size_t
strlcpy(char *dst, const char *src, size_t len)
{
size_t cnt = 0;
len--;

while('\0' != src[cnt] && cnt < len)
{
dst[cnt] = src[cnt];
cnt++;
}

out[cnt] = '\0';
return cnt;
}

Cheers,
dandelion.

PS. The above is not tested and may contain errors.


For example, it doesn't match the openbsd definition:

The strlcpy and strlcat functions return the total length of
the string they tried to create. For strlcpy that means the
length of src.

- jonathan
Nov 14 '05 #8

"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...
In article <41************ ***********@dre ader15.news.xs4 all.nl>,
"dandelion" <da*******@mead ow.net> wrote:
"Jonathan Adams" <jw*****@gmail. com> wrote in message
news:jw******** *************** ****@news1nwk.s fbay.sun.com...

<snip>
size_t
strlcpy(char *out, const char *in, size_t len)
{
size_t ret = strlen(in);

if (ret < len) {
(void) strcpy(out, in);
} else {
(void) strncpy(out, in, len - 1);
out[len - 1] = '\0';
}
return (ret);
}

(yes, there are more efficient ways of writing strlcpy())
size_t
strlcpy(char *dst, const char *src, size_t len)
{
size_t cnt = 0;
len--;

while('\0' != src[cnt] && cnt < len)
{
dst[cnt] = src[cnt];
cnt++;
}

out[cnt] = '\0';
return cnt;
}

Cheers,
dandelion.

PS. The above is not tested and may contain errors.


For example, it doesn't match the openbsd definition:


I'm no OpenBSD user, so don't expect me to know their standards.
The strlcpy and strlcat functions return the total length of
the string they tried to create. For strlcpy that means the
length of src.


In this case I would say the OpenBSD definition sucks, since the src string
is not guaranteed *) to be zero teriminated, in which case strlen will
return a preposterous value if you do not SIGSEGV with an out-of-bounds
pointer (you code).

And if it is... Easy... Add a small extra loop counting till the '\0' comes
home.

I still prefer strncpy.

*) it's a library function after all. I know that *in this case* it's
guaranteed.
Nov 14 '05 #9
Jonathan Adams wrote:
.... snip ...
(yes, there are more efficient ways of writing strlcpy())


For example (full file <http://cbfalconer.home .att.net/download>):

#include "strlcpy.h"

/* NOTE: these routines are deliberately designed to
not require any assistance from the standard
libraries. This makes them more useful in any
embedded systems that must minimize the load size.

Public domain, by C.B. Falconer
bug reports to mailto:cb****** **@worldnet.att .net
*/

/* ---------------------- */

size_t strlcpy(char *dst, const char *src, size_t sz)
{
const char *start = src;

if (src && sz--) {
while ((*dst++ = *src))
if (sz--) src++;
else {
*(--dst) = '\0';
break;
}
}
if (src) {
while (*src++) continue;
return src - start - 1;
}
else if (sz) *dst = '\0';
return 0;
} /* strlcpy */

/* ---------------------- */

size_t strlcat(char *dst, const char *src, size_t sz)
{
char *start = dst;

while (*dst++) /* assumes sz >= strlen(dst) */
if (sz) sz--; /* i.e. well formed string */
dst--;
return dst - start + strlcpy(dst, src, sz);
} /* strlcat */

--
"I support the Red Sox and any team that beats the Yankees"
"Any baby snookums can be a Yankee fan, it takes real moral
fiber to be a Red Sox fan" - "I listened to Toronto come back
from 3:0 in '42, I watched Boston come back from 3:0 in '04"
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
15699
by: ­m½Z | last post by:
I am a C programming beginner... I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string. Because when I output the copied string, it output more than what I want, until I put '\0' at the end by myself. But, sometime I don't need put '\0' and it work well?? Like strncpy(s, t, n); strcat(s, t1); .....
27
2301
by: Shagy | last post by:
Greetings, I've been trying to find an equivant c funtion to the c++ copy function. Description: copy(char *cstring, size_t count, size_t offset); Copies "count" characters from a C-style string starting at offset.
17
2810
by: G Patel | last post by:
E. Robert Tisdale wrote: > > int main(int argc, char* argv) { > quad_t m = {0, 1, 2, 3}; > int r; > fprintf(stdout, "m = ("); > for (size_t j = 0; j < 4; ++j) Why did you declare j as type size_t ?
17
3060
by: lovecreatesbeauty | last post by:
1. In the following code, is the code (line 11) legal? Is there a notice in the document to tell callers that the parameter s1 should receive an array variable, i.e. type char, but not a variable of char *? p1 and p2 point to the same things but they must be declared as different types? Is it nature? char p1 = "hello123456"; char *p2 = "world"; strncpy(p1, p2, strlen(p2));
27
2299
by: smnoff | last post by:
How does( or should user use) strncpy() to allocate enough memory space for the destination string, s1? I guess I am having trouble using strncpy as it seems to be giving me errors. And just as well, I don't know the value of n until the program runs, so it needs to be dynamically allocated. Then again I hard coded n to be number like3 just to even see if that works.
43
4943
by: Frodo Baggins | last post by:
Hi all, We are using strcpy to copy strings in our app. This gave us problems when the destination buffer is not large enough. As a workaround, we wanted to replace calls to strcpy with strncpy. That is, replace calls to strcpy with say, my_strcpy(dest,src) which will internally find the destination buffer length. For this we need to know the destination buffer size. For statically allocated strings sizeof is returning the length of the...
4
9539
by: chikito.chikito | last post by:
1. Can someone tell me the difference between these two functions: void strcpy(char *s1, const char *s2) { while(*s1++ = *s2++) ; } //function prototype of strcpy follows char *strcpy(char *s1, const char *s2) // library function
4
5772
by: lurch132002 | last post by:
i am trying to create an array of structs to hold some information but whenever i get to the second element and try to strncpy it i get a segmenation fault. ive searched around for similar problems but i cant seem to figure out what im doing wrong. any help would be appreciated. #include <stdio.h> #include <stdlib.h> #include <string.h>
2
2454
by: lovecreatesbea... | last post by:
Do I need to repeat inserting '\0' n - strlen(src) times in case strlen(str) less than n. "C: A reference Manual, 5th" mentions this in sec 13.3. "K&RC, 2nd" says that insert one '\0' under the same condition in sec B.3. Thank you for your time. / *******************************************************************************
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9531
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10459
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10187
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9055
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6795
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5446
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3735
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.