For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > May 2004 > Using popen get extra characters(specially HP) when saving in file









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Using popen get extra characters(specially HP) when saving in file
Gonzalo

2004-05-12, 9:08 pm

I want to execute somo UNIX commands from C, encrypt it and save it in
a file. Everytinh works fine, but sometimes(especially in HP-UX),'i've
got extar charactes in my file. Here is a sample code:
FILE *logFile;
char buffer[BUFSIZ],logString[BUFSIZ],logStringCrypt[BUFSIZ];


sprintf(comando,"ps -ef|grep sh");
if ((licmonPipe = popen(comando, "r")) != NULL) {
while (fgets(buffer, BUFSIZ, licmonPipe) != NULL){
cleanStringW(buffer); /* (Delete newline)*/
sprintf(logString,"PSINFO%s",buffer);
encipher(logString, logStringCrypt,"123456789");

fprintf(logFile, "%s\n", logStringCrypt);
}
}
pclose(licmonPipe);
......

void encipher(v,w,k)
char *v;
char *w;
char *k;
{
int i;
int key=0;
char ki[2],aux;

for (i=0;v[i] != '\0';i++) {
ki[0] = k[i%10];
key = atoi(ki);
aux = v[i] + key;
w[i] = aux;
}
w[i]='\0';
}
In the file I've got my info encrypted, but suddenly appear strange
characters like;
06728396856\310\200I\214S\224q\211h6\302
\203N\207e\322\244\275\240k\247\260\213u
C^? auW%a\243\215\266\226\322\252\266\245fak
J\206S\220zu
W6\304\200N\206C^?q\203g%r{S\207T\231v\207WD\20

Someone have any idea???????????????
In Solaris I don't have this problem!!!!!!!!!!!!!!!!!!!
What are these characters??????????????????????????????
Thanks

Gonzalo.
Jens.Toerring@physik.fu-berlin.de

2004-05-12, 9:08 pm

Gonzalo <gonzalo_segarra@hotmail.com> wrote:
> I want to execute somo UNIX commands from C, encrypt it and save it in
> a file. Everytinh works fine, but sometimes(especially in HP-UX),'i've
> got extar charactes in my file. Here is a sample code:
> FILE *logFile;
> char buffer[BUFSIZ],logString[BUFSIZ],logStringCrypt[BUFSIZ];



> sprintf(comando,"ps -ef|grep sh");
> if ((licmonPipe = popen(comando, "r")) != NULL) {
> while (fgets(buffer, BUFSIZ, licmonPipe) != NULL){
> cleanStringW(buffer); /* (Delete newline)*/


What happens if there isn't a newline because the input string
was longer that BUFSIZ? Do you make sure there's alway a '\0'
at the end of 'buffer'?

> sprintf(logString,"PSINFO%s",buffer);
> encipher(logString, logStringCrypt,"123456789");


> fprintf(logFile, "%s\n", logStringCrypt);
> }
> }
> pclose(licmonPipe);
> .....


> void encipher(v,w,k)
> char *v;
> char *w;
> char *k;
> {
> int i;
> int key=0;
> char ki[2],aux;


> for (i=0;v[i] != '\0';i++) {
> ki[0] = k[i%10];
> key = atoi(ki);


What do you pass here to atoi()? The first element of the array 'ki'
is for i equal 0 to 8 a character between '1' and '9' (at least for
the string you pass to the function), and for i equals 9 it's the
'\0' character (because you're already at the end of the 'k'-string
which has only 9 "real" characters not 10 - in that case atoi()
hets an empty string and the result isn't defined). But in the other
cases the second element of the 'ki' array is an unitialized value.
On some machines you might be lucky and it's '\0', making a string
out of the 'ki' array, that you then can pass to atoi(), on others
it might be some completely random value. In that case you can't
call atoi() on 'ki' because it's not a string. In some cases it
might even happen that ki[1] is by chance a value that translates
to a character from the number range, and maybe also the value in
the next memory position. In that case 'key' is going to be some
huge number you don't anticipate in your algorithm and you get the
results you've shown below.

> aux = v[i] + key;
> w[i] = aux;
> }
> w[i]='\0';
> }
> In the file I've got my info encrypted, but suddenly appear strange
> characters like;
> 06728396856\310\200I\214S\224q\211h6\302
\203N\207e\322\244\275\240k\247\260\213u
C^? auW%a\243\215\266\226\322\252\266\245fak
J\206S\220zu
> W6\304\200N\206C^?q\203g%r{S\207T\231v\207WD\20


> Someone have any idea???????????????


> In Solaris I don't have this problem!!!!!!!!!!!!!!!!!!!


Perhaps on Solaris by default automatic variables get initialized to
zero. But you shouldn't rely on that and your program is broken the
way you wrote it, otherwise it would work on all machines;-)

Here's a version of your function that should work correctly (but
take care, I didn't test it!):

void encipher( const char *v, chart *w, const char *k )
{
size_t i = 0;
size_t len = strlen( k );
ki[ 2 ] = { 0 };

for ( i = 0; *v != '\0'; i++ ) {
*ki = k[ i % len ];
*w++ = *v++ + atoi( ki );
}
*w = '\0';
}

But there are still a lot of thinks that can go wrong with that function
unless you make sure the string 'k' consists of digits only. A perhaps
faster and more secure version would be

void encipher( const char *v, chart *w, const char *k )
{
size_t i = 0;
size_t len = strlen( k );

for ( i = 0; i < len; i++ )
if ( ! isdigit( k[ i ] ) {
fprintf( stderr, "Invalid key string\n" );
exit( EXIT_FAILURE );
}

for ( i = 0; *v != '\0'; i++ )
*w++ = *v++ + k[ i % len ] - '\0';
*w = '\0';
}

You're also using a method of the declarations of the arguments of
the function that's outdated by more than a decade. Perhaps you
should invest in a slightly newer book on C.

And finally I hope that you don't think that this "encrytion" is
hard to break, given a not too long sample of the output every
hobby-crypthographer will break it in a few minutes, even without
a computer...
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Gonzalo

2004-05-18, 8:39 am

Dear Jens,
I realize a couple of days later about the error on funcion atoi.
The method of the declarations of the arguments of function I use,is
because I need to compile this code in an old version of HP-UX and
needs this kind of declaration, so I make it for portability.

About the encription, I know it is very very simple, but I only need
to make and easy one.

Thanks a lot for your help!!!!!!!!!!!!!
Bye,
Gonzalo.

Jens.Toerring@physik.fu-berlin.de wrote in message news:<2g1uq1F37t39U1@uni-berlin.de>...
> Gonzalo <gonzalo_segarra@hotmail.com> wrote:
>
>
>
> What happens if there isn't a newline because the input string
> was longer that BUFSIZ? Do you make sure there's alway a '\0'
> at the end of 'buffer'?
>
>
>
>
>
> What do you pass here to atoi()? The first element of the array 'ki'
> is for i equal 0 to 8 a character between '1' and '9' (at least for
> the string you pass to the function), and for i equals 9 it's the
> '\0' character (because you're already at the end of the 'k'-string
> which has only 9 "real" characters not 10 - in that case atoi()
> hets an empty string and the result isn't defined). But in the other
> cases the second element of the 'ki' array is an unitialized value.
> On some machines you might be lucky and it's '\0', making a string
> out of the 'ki' array, that you then can pass to atoi(), on others
> it might be some completely random value. In that case you can't
> call atoi() on 'ki' because it's not a string. In some cases it
> might even happen that ki[1] is by chance a value that translates
> to a character from the number range, and maybe also the value in
> the next memory position. In that case 'key' is going to be some
> huge number you don't anticipate in your algorithm and you get the
> results you've shown below.
>
>
>
>
> Perhaps on Solaris by default automatic variables get initialized to
> zero. But you shouldn't rely on that and your program is broken the
> way you wrote it, otherwise it would work on all machines;-)
>
> Here's a version of your function that should work correctly (but
> take care, I didn't test it!):
>
> void encipher( const char *v, chart *w, const char *k )
> {
> size_t i = 0;
> size_t len = strlen( k );
> ki[ 2 ] = { 0 };
>
> for ( i = 0; *v != '\0'; i++ ) {
> *ki = k[ i % len ];
> *w++ = *v++ + atoi( ki );
> }
> *w = '\0';
> }
>
> But there are still a lot of thinks that can go wrong with that function
> unless you make sure the string 'k' consists of digits only. A perhaps
> faster and more secure version would be
>
> void encipher( const char *v, chart *w, const char *k )
> {
> size_t i = 0;
> size_t len = strlen( k );
>
> for ( i = 0; i < len; i++ )
> if ( ! isdigit( k[ i ] ) {
> fprintf( stderr, "Invalid key string\n" );
> exit( EXIT_FAILURE );
> }
>
> for ( i = 0; *v != '\0'; i++ )
> *w++ = *v++ + k[ i % len ] - '\0';
> *w = '\0';
> }
>
> You're also using a method of the declarations of the arguments of
> the function that's outdated by more than a decade. Perhaps you
> should invest in a slightly newer book on C.
>
> And finally I hope that you don't think that this "encrytion" is
> hard to break, given a not too long sample of the output every
> hobby-crypthographer will break it in a few minutes, even without
> a computer...
> Regards, Jens

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com