/* 
GetPassMask v1.0b
-----------------
c0der: cH!cus
eMail: thechicus@gmail.com
Data: 29 Marzo 2006

DESCRIZIONE: Il programma è un'esempio di come programmare un campo password mascherato in 
			 linguaggio C. C'e' una discreta se non ottimale (almeno x ora mi sembra) gestione 
			 dei backspaces, lunghezze massime e minime, asterischi ecc... Questo per evitare 
			 bugs.

La funzione è freeware. Siete liberi di ridistribuirla, modificarla e/o implementarla nei vostri
programmi. Se implementata vorrei essere citato nei credits del programma, magari anche con un
link al mio sito.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void credits();
void GetPassMask(int nMaxLenght,  char *szBuffer, char cPasswordChar);

int main() {

	/* Caratteri massimi inseribili per la password */
    int nLenght = 20;

	/* Si alloca la memoria dinamicamente */
    char* szPassword = (char*)malloc((nLenght+1)*sizeof(char));
	
	/* Mostra i credits */
	credits();
    
    printf("\nPassword (Max %d): ", nLenght);
    
    /* Ecco la funzione, notare il terzo parametro, indica che ogni carattere digitato sarà
       coperto da un'asterisco. */
    GetPassMask(nLenght, szPassword, '*');

    printf("\nPassword is: %s\n\nLenght: %d\n", szPassword, strlen(szPassword));
    
	/* Si disalloca la memoria usata per contenere la passoword */
	free(szPassword);
}

/* PARAMETRI GetPassMask:

nMaxLenght, valore intero che indica il numero di caratteri massimi inseribili durante 
			l'inserimento della password cosi da avere una password limitata.

*szBuffer, puntatore a carattere (ovvero stringa) che alla fine della funzione conterrà
		   la password digitata dall'utente. 

cPasswordChar, carattere che indica quale carattere deve coprire la password durate la 
			   digitazione. Si puo' inserire l'asterisco (Es. '*' ) come avviene piu 
			   comunamente per le password, ma si puo' usare qualsiasi altro carattere 
			   come il cancelletto (Es. '#'). Se questo parametro è 0 allora durante la 
			   digitazione della password si avrà una modalità di inserimento piu "UNIX 
			   Like". Sarà come su UNIX, infatti in quest'ultimo OS le password per 
			   motivi di sicurezza non si vedono mentre vengono digitate (questo per non
			   far vedere la lunghezza della password). 
*/
void GetPassMask(int nMaxLenght, char *szBuffer, char cPasswordChar) {
       char cPw;
       int i = 0;    

       do {
			/* Cattura il tasto premuto e lo memorizza in pw */
            cPw = getch();                                      
            
            /* Se il numero di caratteri è minore di zero il numero dei caratteri è zero */
            if (i < 0) i = 0;                                  
            
            /* Se i è maggiore della lunghezza massima consentita allora i = lunghezza massima */            
            if (i > (nMaxLenght)) i = nMaxLenght;                      
            
            /* Se il tasto premuto NON è INVIO... */
            if (cPw != '\r') {                                  
               
               /* Se il tasto premuto è il backspace... */    
               if (cPw == '\b') {     
				   
                   /* Se cPasswordChar è diverso da 0 cancella un'asterisco */                                         
                   if(cPasswordChar != 0) if (i > 0) putch('\b'); putch(' '); putch('\b');
                   
				   /* Decrementa i per non contare il carattere backspace */
                   i--;
               } else {                      
                   
				   /* Inserisce il carattere nel buffer e incrementa la lunghezza */                                                       
                   szBuffer[i++] = cPw;
                   if (i <= nMaxLenght) 					   
					   if(cPasswordChar != 0) putch(cPasswordChar);
               }
			}
       /* Con la pressione di INVIO finisce l'inserimento della password */            
       } while (cPw != '\r'); 
	
	   /* Inserisce il NULL nell'ultima posizione di buffer per indicare la fine della stringa */
       szBuffer[i] = '\0';
}

void credits() {
     printf("# GetPassMask v1.0b - c0ded by cHicus - http://thechicus.nigx.net\n"
			"# Visit also http://www.pierotofy.it, The Piero Tofy's Programmers Community!\n");
}
