How to use gnu readline to implement "reset password".

How to use gnu readline to implement "Reset password"

Using gnu readline to implement a shell style program is simple, but implementing "Reset password" is a little hard, here is a very complete example .

#include <stdio.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <readline/readline.h>


#define MAX_PW_LEN (256)
#define RED                  "\e[0;31m"
#define GREEN                "\e[0;32m"
#define NONE                 "\e[0m"
#define YELLOW               "\e[1;33m"

static int input_pw_done = 0;
static int input_pw_is_retype = 0;
static char input_pw_real_text[MAX_PW_LEN];
static char input_pw_pw[MAX_PW_LEN] = {0};
static char input_pw_retype_pw[MAX_PW_LEN] = {0};
static int input_pw_result = -1;

#define PROMPT_MAX_LENGTH (256)
static char current_prompt[PROMPT_MAX_LENGTH] = {0};
static void reset_prompt()
{
    snprintf(current_prompt, PROMPT_MAX_LENGTH, "%s%s%s", YELLOW, "dotphoenix@qq.com$ ", NONE);
}
static const char* get_prompt()
{
    if (strlen(current_prompt) == 0){
        reset_prompt();
    }
    return current_prompt;
}

static void set_prompt(const char* prmpt, const char* color)
{
    const char* clr = color;
    if (clr == NULL) {
        clr = YELLOW;
    }
    snprintf(current_prompt, PROMPT_MAX_LENGTH, "%s%s%s", clr, prmpt, NONE);
}



static void init_readline()
{
  /* Allow conditional parsing of the ~/.inputrc file. */
  rl_readline_name = get_prompt();

  /* Tell the completer that we want a crack first. */
  //rl_attempted_completion_function = tab_completion;
  //rl_completion_entry_function = rl_filename_completion_function_default;
  //read_history(history_path);
}

static void uninit_readline()
{
    
}

static void input_pw_replace_pw_chars() 
{
    char* line;
    int i = 0;
    int saved_point = rl_point;;
    line = rl_copy_text(0, rl_end);
    if (strlen(line) > 0) {
        if (strlen(input_pw_real_text) > strlen(line)) { //backspace ?
        int offset = strlen(input_pw_real_text) - strlen(line);
        i = 0;
        while(i < offset) {
                input_pw_real_text[strlen(line) + i] = 0;
                i++;
            }
        }
        else {
            input_pw_real_text[strlen(line) - 1] = line[strlen(line) - 1];
        }
        for(i = 0; i < strlen(line); i++) {
            line[i] = '*';
        }
        rl_replace_line("", 0);
        rl_redisplay();
        rl_replace_line(line, 0);
        rl_point = saved_point;
        rl_redisplay();
        free(line);
    }
    else {
        i = 0;
    }
}

static void input_pw_handle_line(char* line) 
{
    if (input_pw_is_retype == 0) {
        set_prompt("Retype new password:", GREEN);
        rl_set_prompt(get_prompt());
        strncpy(input_pw_pw, input_pw_real_text, MAX_PW_LEN);
    }
    else {
        reset_prompt();
        rl_set_prompt(get_prompt());
        rl_callback_handler_remove();  
        strncpy(input_pw_retype_pw, input_pw_real_text, MAX_PW_LEN);
        
        if (strcmp(input_pw_pw, input_pw_retype_pw) == 0) {
            input_pw_result = 0;
        }
        else {
            const char* p = "Password does not match.";
            strcpy(input_pw_pw, p);
            input_pw_result = -1;
        }
    } 
    input_pw_done = 1;
}
static int readline_input_pw(char* password)
{
    memset(input_pw_real_text, sizeof(char) * MAX_PW_LEN, 0);
    input_pw_done = 0;
    input_pw_is_retype = 0;
    set_prompt("New password:", GREEN);
    rl_callback_handler_install(get_prompt(), input_pw_handle_line);
    
    while (input_pw_done == 0) {
        input_pw_replace_pw_chars();
        rl_callback_read_char();
    }
    
    input_pw_done = 0;
    input_pw_is_retype = 1;
    while (input_pw_done == 0) {
        input_pw_replace_pw_chars();
        rl_callback_read_char();
    }
    
    strcpy(password, input_pw_pw);
    return input_pw_result;
}

static void ssp_printf(const char* color, const char* format, ...)
{
    va_list arg_ptr;
    char msg[4096] = {0};
    va_start(arg_ptr, format);
    
    strcpy(msg, color);
    vsnprintf(msg + strlen (msg), 4096 - 20, format, arg_ptr);
    va_end(arg_ptr);
    strcat(msg, NONE);
    printf(msg);
}

int main(int argc, char **argv)
{
    int done = 0;
    (void)argc;
    (void)argv;

    init_readline();	/* Bind our completer. */

    //tester();
    /* Loop reading and executing lines until the user quits. */
    while (done == 0)
    {
      char* line = readline(get_prompt());
      char* cmd = line;
      if(!line) { // ctrl + d
          ssp_printf(GREEN, "\n");
          continue;
      }
      
      if (strcmp(cmd, "quit!") == 0) {
          done = 1;
      }
      else {
          if (strcmp(cmd, "setpw") == 0) {
            char pw[MAX_PW_LEN] = {0};
            int cr = readline_input_pw(pw);
            if (cr == 0) {
                ssp_printf(GREEN, "Set successfully (%s). \n", pw);
            }
            else {
                ssp_printf(RED, "%s \n", pw);
            }
        }
        else {
            if (strlen(cmd) > 0) {
                ssp_printf(GREEN, "Run %s successfully !!!\n", cmd);
            }
        }
      }
      free (line);
    }
    uninit_readline();
}

Using command below to build:

gcc -o reset_pw  input_pw.c -lreadline


The effect :


./reset_pw 
dotphoenix@qq.com$ setpw
New password:****
Retype new password:****
Set successfully (1111). 
dotphoenix@qq.com$ setpw
New password:*
Retype new password:**
Password does not match. 
dotphoenix@qq.com$ 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值