Drizzled Public API Documentation

get_password.cc

00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 /*
00021 ** Ask for a password from tty
00022 ** This is an own file to avoid conflicts with curses
00023 */
00024 
00025 #include <config.h>
00026 #include <client/get_password.h>
00027 
00028 #include <string>
00029 
00030 #include <string.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <ctype.h>
00034 #include <unistd.h>
00035 
00036 #include <sys/ioctl.h>
00037 #ifdef HAVE_TERMIOS_H       /* For tty-password */
00038 # include <termios.h>
00039 #  define TERMIO  struct termios
00040 #else
00041 #  ifdef HAVE_TERMIO_H        /* For tty-password */
00042 #    include  <termio.h>
00043 #    define TERMIO  struct termio
00044 #  else
00045 #    include  <sgtty.h>
00046 #    define TERMIO  struct sgttyb
00047 #  endif
00048 #endif
00049 
00050 using namespace std;
00051 
00052 bool tty_password= false;
00053 const std::string PASSWORD_SENTINEL("\0\0\0\0\0", 5);
00054 
00055 /*
00056   Can't use fgets, because readline will get confused
00057   length is max number of chars in to, not counting \0
00058   to will not include the eol characters.
00059 */
00060 
00061 static void get_password(char *to, uint32_t length,int fd, bool echo)
00062 {
00063   char *pos=to,*end=to+length;
00064 
00065   for (;;)
00066   {
00067     char tmp;
00068     if (read(fd,&tmp,1) != 1)
00069       break;
00070     if (tmp == '\b' || (int) tmp == 127)
00071     {
00072       if (pos != to)
00073       {
00074   if (echo)
00075   {
00076     fputs("\b \b",stderr);
00077     fflush(stderr);
00078   }
00079   pos--;
00080   continue;
00081       }
00082     }
00083     if (tmp == '\n' || tmp == '\r' || tmp == 3)
00084       break;
00085     if (iscntrl(tmp) || pos == end)
00086       continue;
00087     *(pos++) = tmp;
00088   }
00089   while (pos != to && isspace(pos[-1]) == ' ')
00090     pos--;          /* Allow dummy space at end */
00091   *pos=0;
00092   return;
00093 }
00094 
00095 
00096 char *client_get_tty_password(const char *opt_message)
00097 {
00098   TERMIO org,tmp;
00099   char buff[80];
00100 
00101   if (isatty(fileno(stderr)))
00102   {
00103     fputs(opt_message ? opt_message : "Enter password: ",stderr);
00104     fflush(stderr);
00105   }
00106 #  if defined(HAVE_TERMIOS_H)
00107   tcgetattr(fileno(stdin), &org);
00108   tmp = org;
00109   tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
00110   tmp.c_cc[VMIN] = 1;
00111   tmp.c_cc[VTIME] = 0;
00112   tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
00113   get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr)));
00114   tcsetattr(fileno(stdin), TCSADRAIN, &org);
00115 #  elif defined(HAVE_TERMIO_H)
00116   ioctl(fileno(stdin), (int) TCGETA, &org);
00117   tmp=org;
00118   tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
00119   tmp.c_cc[VMIN] = 1;
00120   tmp.c_cc[VTIME]= 0;
00121   ioctl(fileno(stdin),(int) TCSETA, &tmp);
00122   get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
00123   ioctl(fileno(stdin),(int) TCSETA, &org);
00124 #  else
00125   gtty(fileno(stdin), &org);
00126   tmp=org;
00127   tmp.sg_flags &= ~ECHO;
00128   tmp.sg_flags |= RAW;
00129   stty(fileno(stdin), &tmp);
00130   get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
00131   stty(fileno(stdin), &org);
00132 #  endif
00133   if (isatty(fileno(stderr)))
00134     fputc('\n',stderr);
00135 
00136   return strdup(buff);
00137 }
00138 
00139 pair<string, string> parse_password_arg(string s)
00140 {
00141   if (s.find("--password") == 0)
00142   {
00143     if (s == "--password")
00144     {
00145       tty_password= true;
00146       //check if no argument is passed.
00147       return make_pair("password", PASSWORD_SENTINEL);
00148     }
00149 
00150     if (s.substr(10,3) == "=\"\"" || s.substr(10,3) == "=''")
00151     {
00152       // Check if --password="" or --password=''
00153       return make_pair("password", PASSWORD_SENTINEL);
00154     }
00155     
00156     if(s.substr(10) == "=" && s.length() == 11)
00157     {
00158       // check if --password= and return a default value
00159       return make_pair("password", PASSWORD_SENTINEL);
00160     }
00161   }
00162 
00163   return make_pair(string(""), string(""));
00164 }
00165