Thread: hide what's written to a file

  1. #1
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92

    hide what's written to a file

    I want to write something to a file, but I don't want what the user types to show up in the Terminal. How can this be done?

    Thanks in advance.

  2. #2
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92
    Thank you for replying. I did a search for encryption, but didn't find anything after skimming through some of the results. Maybe it's me that's slow, but how can this come under the category encryption? I don't want anything encrypted - I just want zero output to the Terminal.

  3. #3
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    getch()
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  4. #4
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92
    Thank you. I've read a bit in getch()'s man page, but it makes very little sense. I've also tried to use noecho(), but no matter what function I use from the <curses.h>, all I get is errors. The compiler keeps complaining about symbols that aren't found. What am I missing? Is there a tutorial out there (I didn't manage to locate any with google) on getch() or noecho()?

  5. #5
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    post your code so we can read it and help you

  6. #6
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    i think you need to do
    Code:
    gcc curses.c -o curses -lcurses

    -LC
    Last edited by Lynux-Penguin; 08-30-2003 at 01:46 PM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  7. #7
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92
    Lynux-Penguin: Thank you, it compiles now.

    After doing some research I'm not sure I'm on the right track. I found an example where getch() was used, and it was an application that drew a window and such in the Terminal. It also printed out 'hello' when enter was presses. All I want to do it hide the output from the Terminal (meaning that whatever's happening is not related to any specific key). Can this be done with writing the input byte-by-byte to the file? Or can really the getch() be used to hide the letters typed by the user?

    The code, which is far from completed, looks like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <curses.h>
    
    int main() {
    
        FILE *inputFile;
        char fileName[15] = "input.txt";
        char userInput[100] = { 0 };
    
        printf("type something: ");
    
        inputFile = fopen(fileName, "wa");
    
        if(inputFile == NULL) {
            fprintf(stderr, "aborted: NULL error while open readFile\n");
            exit(0);
        }
    
        // the input from the user should be hidden with something here
    
        fgets(userInput, sizeof(userInput), stdin);
    
        fwrite(userInput, 100, sizeof(char), inputFile);
        rewind(inputFile);
    
        fclose(inputFile);
    
        return 0;
    }

  8. #8
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    I think you're looking for a method to un-echo the terminal.

    here's an example program I wrote to use termios to disable echoing (thanks to a post made by prelude) I used it to read in a password, actually just a regular string but the point is that its hidden.

    Code:
    #include <termios.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    enum
    { ON, OFF };
    
    int setEcho(int mode)
    {
      struct termios tios;
      if(tcgetattr(STDIN_FILENO,&tios)!=0)
      {
        fprintf(stderr, "error on line %d, tcgetattr()\n",__LINE__-2);
        abort(); //dump the core and die
      }
    
      if(mode==OFF)
            tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
      else if(mode==ON)
            tios.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
      else
      {  fprintf(stderr,"invalid mode, aborting...\n"); abort(); }
      if(tcsetattr(STDIN_FILENO,TCSANOW,&tios)!=0)
      {
        fprintf(stderr, "error on line %d, tcsetattr()\n",__LINE__-2);
        abort(); //dump the core and die
      }
      return 0;
    }
    int main()
    {
      char pass[16];
      printf("Enter pass: ");
      setEcho(OFF);
      fgets(pass,16,stdin);
      setEcho(ON);
      printf("%s\n",pass);
      return 0;
    }
    see, no curses ^_^

    for more information on termios:

    http://www.rt.com/man/termios.3.html

    and http://www.faqs.org/docs/Linux-HOWTO...ing-HOWTO.html

    -LC
    Last edited by Lynux-Penguin; 08-30-2003 at 02:27 PM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  9. #9
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    try using this instead of the call to fgets().
    Code:
    int count=0;
    char buff;
    
    for(count=0;(buff=getch()!='\r')&&count<100;count++)
    {
     userInput[count]=getch(); /*moves character to string*/
     printf("*");  /*if you want to show characters being put in*/
    }

  10. #10
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    you could do it that way too, i suppose, i haven't noticed any real difference. getch essentially does the same thing as:
    Code:
    int getch()
    {
      int c;
      setEcho(OFF); 
      c=getc(); 
      setEcho(ON);
      return c;
    }
    -LC
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  11. #11
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92
    I'm still having some minor troubles, but you guys rock!
    Code:
    int count=0;
    char buff;
    
    for(count=0;(buff=getch()!='\r')&&count<100;count++)
    {
     userInput[count]=getch(); /*moves character to string*/
     printf("*");  /*if you want to show characters being put in*/
    }
    I tried to put this in my source code instead of the fgets() line, but it didn't quite work. I got this running my program:
    type something: test
    ************************************************** **************************************************
    I guess I'm missing something vital here.. And, btw, what is this line really doing: userInput[count]=getch();
    It's the []'s that confuses me.

    Lynux-Penguin: Your code definitely did the job. The problem is that the code is a bit above my level, so I'll try to avoid it if I can (I don't like using code I don't understand). - But I will use it my program, ofc by giving you the proper credit, if needed. And thanks for the links, I'll be checking them out!

  12. #12
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    hey i know how you feel but the reason his code doesn't work is because his end-input exception is '\r' which I have no idea what that is, change it to '\n' and it should work fine.

    the reason you get that output is because the loop just runs until 100

    -LC
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  13. #13
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    to make the asterisk's stop appearing, just remove the line
    Code:
    printf("*");
    I only put this in because many times you enter a password it shows an asterisk instead of what you typed in. I included this in case you wanted the user to have a reference of how many characters he/she typed.

    The line userInput[count] goes through each part of the userInput array and puts in the letter called by getch(). I actually wrote that line wrong, it's supposed to be
    Code:
    userInput[count]= buff;
    I'm sorry for my mistake
    It should work fine for you now

    [edit]
    to respond to linux-penguin's message, I may have been incorrect in giving the '/r' conditional. It has worked for me many times before, and is something I should wean myself off of
    [/edit]
    Last edited by Draco; 08-30-2003 at 04:14 PM.

  14. #14
    UNIX chick
    Join Date
    Mar 2003
    Posts
    92
    hehe, I'm kinda confused. It still doesn't work. Or, it works in the opposite way. I can type a word, which isn't entered in the file, but I want what I wrote to appear in the file (but not on the screen). Just to be sure, here's the code:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <curses.h>
    
    int main() {
    
        FILE *inputFile;
        char fileName[15] = "input.txt";
        char userInput[100] = { 0 };
        int count=0;
        char buff;
    
        printf("type something: ");
    
        inputFile = fopen(fileName, "wa");
    
        if(inputFile == NULL) {
            fprintf(stderr, "aborted: NULL error while open readFile\n");
            exit(0);
        }
        
        fgets(userInput, sizeof(userInput), stdin);
        
        for(count=0; (buff=getch()!='\n') && count < 100; count++) {
            userInput[count]= buff;		/* moves character to string*/
            printf("*");  				/* if you want to show characters being put in*/
        }
    
        fwrite(userInput, 100, sizeof(char), inputFile);
        rewind(inputFile);
    
        fclose(inputFile);
    
        return 0;
    }
    I realize I wrote something wrong in my last post. I didn't remove the fgets() line (if I do there's no way to get the input). I have tried to run the program without the fgets() line too, but it results in nothing useful. Sorry if I have confused you, I know for sure I'm confused. And, thanks for all the help so far, it's highly appreciated.

  15. #15
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    Code:
    int count=0;
    char buff;
    char userInput[100]; /* remember to fill the full word buffer ADDED */
    bool charReplace=true; /* if you want the *s to fill the input */
    
    for(count=0;(buff=getch()!='\n')&&count<100;count++) /* '\r' -> '\n'  ADDED */
    {
     userInput[count]=getch(); /*moves character to string*/  /* brilliant! */
     if(charReplace)
       printf("*");  /*if you want to show characters being put in*/
    }
    like this Draco?

    >hehe, I'm kinda confused. It still doesn't work. Or, it works in
    >the opposite way. I can type a word, which isn't entered in the
    >file, but I want what I wrote to appear in the file (but not on the
    >screen). Just to be sure, here's the code:

    well first off you shouldn't do
    Code:
    fgets(str, sizeof(str), stdin);
    it should be done more like:
    Code:
    fgets(str,strlen(str),stdin);
    also I think you might want to see this:
    Code:
    DESCRIPTION
           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.  Depending on the  setting  of  cbreak,  this  is
           after one character (cbreak mode), or after the first new_
           line (nocbreak mode).  In  half-delay  mode,  the  program
           waits  until a character is typed or the specified timeout
           has been reached.
    and because there is nothing in the input buffer, it just returns ERR.


    for a better version of getch (in my opinion)

    Code:
    #include <termios.h>
    #include <stdio.h>
    #include <unistd.h>
    int vVv_getch()
    {
      int ch;
      struct termios oldt,newt;
      if(tcgetattr(STDIN_FILENO,&oldt)!=0)
        return -1;
      newt = oldt;
      newt.c_lflag &= ~( ICANON | ECHO ); //disables echo and icanonical mode (no buffer)
      newt.c_cc[VMIN] = 1;
      newt.c_cc[VTIME] = 0;
      if( tcsetattr(STDIN_FILENO,TCSANOW,&newt) != 0 )
        return -1;
      ch = getchar();
      if( tcsetattr(STDIN_FILENO,TCSANOW, &oldt) != 0 )
        return -1;
      return ch;
    }
    for more info see the Linux board FAQ

    every way I look at it your going to end up coming back to termios, unless someone can modify the terminal no_break mode without using termios... if you find a solution other than this, let me know please.


    -LC
    Last edited by Lynux-Penguin; 08-30-2003 at 04:50 PM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Reading a file written by VB
    By nemaroller in forum C++ Programming
    Replies: 8
    Last Post: 07-12-2002, 11:17 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM