Hi,
I am writing a small program ( still quite new to this), and i need to hide the input that the user enters (as su does for example, you cant see what you are typing). How can i do this?
Printable View
Hi,
I am writing a small program ( still quite new to this), and i need to hide the input that the user enters (as su does for example, you cant see what you are typing). How can i do this?
You might want to have a look at this thread, it basically explains everything you want to do.
Hi,
Thanks for the reply, but its not quite working yet.
I now have the following code:
I then compile it withCode:#include <stdlib.h>
#include <curses.h>
#include <stdio.h>
void passgets(char pword[], int maxlength)
{
int counter = 0;
char ch;
while( (ch = getch() ) != '\r' && counter < maxlength-1 )
{
if(ch == '\b' && counter > 0)
{
printf("\b \b");
counter--;
}
else
{
pword[counter++] = ch;
putchar('*');
}
}
pword[counter] = '\0';
}
int main()
{
char password[20];
passgets(password, 19);
return 1;
}
gcc prog.c -o prog -lcurses
When I run the program all it does is print 19 *'s and exits, doesnt take any input, etc. What could it be?
LOL. Well, it does store the input, but what else do you want it to do? You told it to store the input, hide the text, and then quit.
No what it is supposed to do is the following:
every time a key is pressed, it is added to the character buffer and a * is printed. Once the user pressed enter it quits
What it currently does is, when run, it prints 19 *'s and quits, as if my whole program consisted of printf("*******************");
Try changing the '\r' to '\n'.
nah same result :(
btw. im running ubuntu if that matters
edit:
its strange... in theory it should work, but it is as if some is pressing a key on the keyboard and as soon as the program is run it fills up with crap
I don't have the curses library so I can't play with it at the moment. Sorry.
I wish we had a more standard way of doing these kind of things. As it stands, you have to fight with the libraries or manage it via O/S specific methods. Kind of annoying actually.
I was looking at the man pages of getch and i read the following:
What is this no-delay mode and does it have to do with that?Quote:
The getch, wgetch, mvgetch and mvwgetch, routines read a character from
the window. In no-delay mode, if no input is waiting, the value ERR is
returned. In delay mode, the program waits until the system passes
text through to the program.
The quote you gave explains what no-delay mode is.
To expand ....
The behaviour of getch() and related functions is affected by settings that your program can control. One of those settings is no-delay mode which is changed using the nodelay() function -- Enter "man nodelay" (I seem to recall it's "man 3 nodelay" for the library function, but may be wrong on that) for information on the function call.
In no-delay mode, if there is no input pending, getch will return an error status. This is potentially useful if you want to poll for user input, but do something (eg count down for some period, so the program effectively only waits for a fixed time for input, but tells the user how long is remaining).
If not in no-delay mode, if there is no input pending, getch() will sit and wait until input is available.
Thanks for the reply, but I finally found something that works. It is slightly above my head but i am trying to fully understand what it does. BTW backspaces dont work here, any ideas on that?
Only thing is backspace doesnt work, any ideas on that?Code:#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <ctype.h>
int mygetch ( void )
{
int ch;
struct termios oldt, newt;
tcgetattr ( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
int main()
{
int ch;
char pword[BUFSIZ];
int i = 0;
puts ("Enter your password");
fflush(stdout);
while ((ch = mygetch()) != EOF
&& ch != '\n'
&& ch != '\r'
&& i < sizeof(pword) - 1)
{
if (ch == '\b' && i > 0)
{
printf("\b \b");
fflush(stdout);
i--;
pword[i] = '\0';
}
else if (isalnum(ch))
{
putchar('*');
pword[i++] = (char)ch;
}
}
pword[i] = '\0';
printf ("\nYou entered >%s<", pword);
return 0;
}
What do you get as output, for example?
With the new code (i.e. the code I posted above), I see everything I typed. What this means is that backspaces are effectively ignored, so if i type "hi <backspace>a" (intending to type ha), it will print hia.
I have my reservations about what you're doing.
First of all, please observe that <conio.h> and <ncurses.h> implement different versions of getch(). I only say this because it appears that you've been using the code from the FAQ to do what you want. This is normally a good thing, but the code you borrowed relies on <conio.h> and its implementation of getch: you cannot mix and match libraries. If you want to use the <ncurses.h> library, then develop your application in accordance with the library's documentation. (read: I think you have to call initscr() and do some other things before input functions can work the way you expect them to.)
It's perfectly fine if you don't want to use <ncurses.h> by the way, you can always use something else, like <termios.h>. But you should realize too that you cannot mix Standard and non-Standard code. The Standard only guarantees anything while you are in accordance with its rules.
What I mean is that getchar is the root of your problem. Check out this average, untested fetch_string function:
getchar is implemented in such a way that allows the terminal to take care of rubout. It has no knowledge of the mistakes you make and happily returns anything in the C character set. The only reason that my function works is probably due to an intelligent environment and the fact that I'm completely following the Standard, and operating directly on the C string. Because your code never encounters the backspace character, the counter cannot be adjusted and therefore you end up with mistaken passwords, prematurely cut off passwords thanks to mistakes, et cetera. I was able to diagnose this problem because you provided the output though, thanks for cooperating. :)Code:char * fetch_string ( char * s, unsigned int n ) {
if ( s ) {
unsigned int i;
int ch;
for ( i = 0; i < n - 2; i++ ) {
ch = getchar( );
if( ch != '\n' && ch != EOF )
s[i] = ch;
else
break;
}
s[i] = '\0';
}
return s;
}
That's not to say what you have implemented already is a step in the wrong direction, I'm just not very familiar with the library you are using now. If termios implements a character grabbing function, use that. If not, forget about it and go back to ncurses and try again.