Merged from silc_1_0_branch.
[silc.git] / lib / silcutil / silcutil.c
index 9b0294e8a9ba632aab0fa34d4019561b8f568c57..8c9064891527f6199d346681f9d3a38cf3cb0d53 100644 (file)
@@ -389,7 +389,7 @@ int silc_string_compare(char *string1, char *string2)
   slen2 = strlen(string2);
 
   /* See if they are same already */
-  if (!strncmp(string1, string2, strlen(string2)))
+  if (!strncmp(string1, string2, slen2) && slen2 == slen1)
     return TRUE;
 
   if (slen2 < slen1)
@@ -657,15 +657,25 @@ char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
 
   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
     strncat(string, "M", 1);
+  
+  if (mode & SILC_CHANNEL_MODE_CIPHER)
+    strncat(string, "c", 1);
+  
+  if (mode & SILC_CHANNEL_MODE_HMAC)
+    strncat(string, "h", 1);
 
   if (mode & SILC_CHANNEL_MODE_CIPHER) {
-    if (strlen(cipher) + strlen(string) < sizeof(string))
+    if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
+      strncat(string, " ", 1);
       strncat(string, cipher, strlen(cipher));
+    }
   }
 
   if (mode & SILC_CHANNEL_MODE_HMAC) {
-    if (strlen(hmac) + strlen(string) < sizeof(string))
+    if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
+      strncat(string, " ", 1);
       strncat(string, hmac, strlen(hmac));
+    }
   }
 
   /* Rest of mode is ignored */
@@ -871,11 +881,12 @@ SilcUInt32 silc_version_to_num(const char *version)
 char *silc_get_input(const char *prompt, bool echo_off)
 {
 #ifdef SILC_UNIX
+  int fd;
+  char input[2048];
+
   if (echo_off) {
     char *ret = NULL;
 #ifdef HAVE_TERMIOS_H
-    char input[2048];
-    int fd;
     struct termios to;
     struct termios to_old;
 
@@ -891,8 +902,10 @@ char *silc_get_input(const char *prompt, bool echo_off)
     tcgetattr(fd, &to);
     to_old = to;
 
-    /* Echo OFF */
+    /* Echo OFF, and assure we can prompt and get input */
     to.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+    to.c_lflag |= ICANON;
+    to.c_cc[VMIN] = 255;
     tcsetattr(fd, TCSANOW, &to);
 
     memset(input, 0, sizeof(input));
@@ -902,6 +915,7 @@ char *silc_get_input(const char *prompt, bool echo_off)
 
     if ((read(fd, input, sizeof(input))) < 0) {
       fprintf(stderr, "silc: %s\n", strerror(errno));
+      tcsetattr(fd, TCSANOW, &to_old);
       return NULL;
     }
 
@@ -917,15 +931,11 @@ char *silc_get_input(const char *prompt, bool echo_off)
     tcsetattr(fd, TCSANOW, &to_old);
     signal(SIGINT, SIG_DFL);
 
-    ret = silc_calloc(strlen(input), sizeof(char));
-    memcpy(ret, input, strlen(input));
+    ret = silc_memdup(input, strlen(input));
     memset(input, 0, sizeof(input));
 #endif /* HAVE_TERMIOS_H */
     return ret;
   } else {
-    char input[2048];
-    int fd;
-
     fd = open("/dev/tty", O_RDONLY);
     if (fd < 0) {
       fprintf(stderr, "silc: %s\n", strerror(errno));
@@ -1030,6 +1040,9 @@ static const SilcStatusMessage silc_status_messages[] = {
   { STAT(BAD_SERVER_ID), "Server ID is not valid" },
   { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
   { STAT(BAD_VERSION), "Bad version" },
+  { STAT(TIMEDOUT), "Service timed out" },
+  { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
+  { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
 
   { 0, NULL }
 };
@@ -1139,3 +1152,16 @@ const char *silc_get_command_name(unsigned char command)
     return "UNKNOWN";
   return command_name[command];
 }
+
+/* Return TRUE if `smaller' is smaller than `bigger'. */
+
+bool silc_compare_timeval(struct timeval *smaller, 
+                         struct timeval *bigger)
+{
+  if ((smaller->tv_sec < bigger->tv_sec) ||
+      ((smaller->tv_sec == bigger->tv_sec) &&
+       (smaller->tv_usec < bigger->tv_usec)))
+    return TRUE;
+
+  return FALSE;
+}