Changeset e2cbbbe


Ignore:
Timestamp:
Apr 8, 2010, 10:00:41 PM (14 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.10, release-1.6, release-1.7, release-1.8, release-1.9
Children:
b094191
Parents:
8a5b5a1 (diff), 9a7b4f2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge branch 'refactor-zcrypt'
Files:
3 added
26 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r1703f72 r7d03c8d  
    1515autom4te.cache
    1616barnowl.bin
     17zcrypt
    1718blib
    1819config.cache
  • Makefile.am

    r10557e6 r7d03c8d  
    55
    66bin_PROGRAMS = barnowl.bin
     7if ENABLE_ZCRYPT
     8bin_PROGRAMS += zcrypt
     9endif
     10
     11zcrypt_SOURCES = zcrypt.c filterproc.c
     12
    713check_PROGRAMS = tester perl_tester
    814
    915barnowl_bin_SOURCES = $(BASE_SRCS) \
    1016     owl.h owl_perl.h config.h \
    11      owl.c \
     17     owl.c filterproc.c \
    1218     $(GEN_C) $(GEN_H)
    1319
     
    3844     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
    3945     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
    40      keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
     46     keypress.c keymap.c keybinding.c cmd.c context.c \
    4147     aim.c buddy.c buddylist.c style.c errqueue.c \
    4248     zbuddylist.c popexec.c obarray.c select.c wcwidth.c \
  • barnowl

    rd5ef539 r9a7b4f2  
    1313
    1414export BARNOWL_DATA_DIR="$SRCDIR/perl/"
     15export BARNOWL_BIN_DIR="$SRCDIR/"
    1516exec "$EXE" "$@"
  • commands.c

    r8a5b5a1 re2cbbbe  
    20222022char *owl_command_zcrypt(int argc, const char *const *argv, const char *buff)
    20232023{
    2024 #ifdef OWL_ENABLE_ZCRYPT
    20252024  owl_zwrite z;
    20262025
     
    20442043  }
    20452044  return(NULL);
    2046 #else
    2047   owl_function_makemsg("This Owl does not support zcrypt");
    2048   return NULL;
    2049 #endif
    20502045}
    20512046
  • configure.ac

    r2d3ed95 re2cbbbe  
    6565
    6666AC_CHECK_FUNCS([use_default_colors resizeterm])
    67 AC_CHECK_FUNCS([des_string_to_key des_key_sched des_ecb_encrypt])
    68 AC_CHECK_FUNCS([DES_string_to_key DES_ecb_encrypt DES_key_sched])
     67AC_CHECK_FUNCS([des_string_to_key DES_string_to_key], [HAVE_DES_STRING_TO_KEY=1])
     68AC_CHECK_FUNCS([des_ecb_encrypt DES_ecb_encrypt], [HAVE_DES_ECB_ENCRYPT=1])
     69AC_CHECK_FUNCS([des_key_sched DES_key_sched], [HAVE_DES_KEY_SCHED=1])
    6970
    7071dnl Checks for header files.
     
    118119AC_DEFINE_UNQUOTED([DATADIR],["${prefix}/share/${PACKAGE}"],
    119120                   [Package data directory])
     121AC_DEFINE_UNQUOTED([BINDIR],["${prefix}/bin"],
     122                   [Binary directory])
    120123
    121124dnl Checks for typedefs, structures, and compiler characteristics.
     
    126129AX_C_CHECK_FLAG([-Wno-pointer-sign],[],[],
    127130  [LIBFAIM_CFLAGS="$LIBFAIM_CFLAGS -Wno-pointer-sign"])
     131
     132AM_CONDITIONAL([ENABLE_ZCRYPT], [test "$HAVE_DES_STRING_TO_KEY" && dnl
     133                                 test "$HAVE_DES_KEY_SCHED" && dnl
     134                                 test "$HAVE_DES_ECB_ENCRYPT"])
    128135
    129136AC_SUBST([LIBFAIM_CFLAGS])
  • functions.c

    r8a5b5a1 re2cbbbe  
    1212#include <signal.h>
    1313#include "owl.h"
     14#include "filterproc.h"
    1415
    1516char *owl_function_command(const char *cmdbuff)
     
    399400  char *cryptmsg;
    400401  owl_message *m;
     402  const char *argv[7];
     403  char *zcrypt;
     404  int rv, status;
    401405
    402406  /* create the zwrite and send the message */
     
    408412
    409413  mymsg=owl_zwrite_get_message(&z);
    410 #ifdef OWL_ENABLE_ZCRYPT
    411   cryptmsg = owl_zcrypt_encrypt(mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z));
    412   if (!cryptmsg) {
     414
     415  zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir());
     416  argv[0] = "zcrypt";
     417  argv[1] = "-E";
     418  argv[2] = "-c"; argv[3] = owl_zwrite_get_class(&z);
     419  argv[4] = "-i"; argv[5] = owl_zwrite_get_instance(&z);
     420  argv[6] = NULL;
     421
     422  rv = call_filter(zcrypt, argv, mymsg, &cryptmsg, &status);
     423
     424  owl_free(zcrypt);
     425
     426  if (rv || status) {
     427    if(cryptmsg) owl_free(cryptmsg);
    413428    owl_function_error("Error in zcrypt, possibly no key found.  Message not sent.");
    414429    owl_function_beep();
     
    416431    return;
    417432  }
    418 #else
    419   cryptmsg=owl_strdup(mymsg);
    420 #endif
    421433
    422434  owl_zwrite_set_message(&z, cryptmsg);
  • message.c

    r66a8cd6 r9a7b4f2  
    1010#include <time.h>
    1111#include "owl.h"
     12#include "filterproc.h"
    1213
    1314static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
     
    838839  owl_free(tmp);
    839840
    840 #ifdef OWL_ENABLE_ZCRYPT
    841841  /* if zcrypt is enabled try to decrypt the message */
    842842  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
    843     char *out = owl_zcrypt_decrypt(owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
    844     if (out) {
     843    const char *argv[] = {
     844      "zcrypt",
     845      "-D",
     846      "-c", owl_message_get_class(m),
     847      "-i", owl_message_get_instance(m),
     848      NULL
     849    };
     850    char *out;
     851    int rv;
     852    int status;
     853    char *zcrypt;
     854
     855    zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir());
     856
     857    rv = call_filter(zcrypt, argv, owl_message_get_body(m), &out, &status);
     858    owl_free(zcrypt);
     859
     860    if(!rv && !status) {
     861      int len = strlen(out);
     862      if(len >= 8 && !strcmp(out + len - 8, "**END**\n")) {
     863        out[len - 8] = 0;
     864      }
    845865      owl_message_set_body(m, out);
    846866      owl_free(out);
     867    } else if(out) {
     868      owl_free(out);
    847869    }
    848870  }
    849 #endif 
    850871}
    851872#else
  • tester.c

    r30bb10a rd564c3d  
    1313int owl_obarray_regtest(void);
    1414int owl_editwin_regtest(void);
    15 #ifdef OWL_ENABLE_ZCRYPT
    16 int owl_zcrypt_regtest(void);
    17 #endif
    1815
    1916int main(int argc, char **argv, char **env)
     
    3633  numfailures += owl_obarray_regtest();
    3734  numfailures += owl_editwin_regtest();
    38 #ifdef OWL_ENABLE_ZCRYPT
    39   numfailures += owl_zcrypt_regtest();
    40 #endif
    4135  if (numfailures) {
    4236      fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
     
    367361  return numfailed;
    368362}
    369 
    370 #ifdef OWL_ENABLE_ZCRYPT
    371 int owl_zcrypt_regtest(void)
    372 {
    373   int numfailed = 0;
    374   char *encrypted, *decrypted;
    375 
    376   printf("# BEGIN testing owl_zcrypt\n");
    377 
    378   encrypted = owl_zcrypt_encrypt_with_key("Hello, world!", "seekritkey");
    379   FAIL_UNLESS("zcrypt encrypt", strcmp(encrypted, "TLJMKQSIGKSJRIJRSIIPIJFFULKRJSPK") == 0);
    380   decrypted = owl_zcrypt_decrypt_with_key(encrypted, "seekritkey");
    381   FAIL_UNLESS("zcrypt decrypt", strcmp(decrypted, "Hello, world!") == 0);
    382   owl_free(decrypted);
    383   owl_free(encrypted);
    384 
    385   printf("# END testing owl_zcrypt (%d failures)\n", numfailed);
    386 
    387   return numfailed;
    388 }
    389 #endif
  • util.c

    rf449096 r9a7b4f2  
    609609}
    610610
     611const char * owl_get_bindir(void)
     612{
     613  const char * bindir = getenv("BARNOWL_BIN_DIR");
     614  if(bindir != NULL)
     615    return bindir;
     616  return BINDIR;
     617}
     618
    611619/* Strips format characters from a valid utf-8 string. Returns the
    612620   empty string if 'in' does not validate. */
  • zcrypt.c

    rf8074e9 re832a52  
    1 /* This file is stolen and slightly modified code */
    2 
    31/* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted *
    42 *   datastream.  Reads the string to make the key from from the first       *
     
    108
    119#include <stdio.h>
    12 #include <stdlib.h>
    13 #include <string.h>
    14 #include <sys/types.h>
    15 #include <sys/wait.h>
    16 #include "owl.h"
    17 
    18 #ifdef OWL_ENABLE_ZCRYPT
    19 
    20 #define BASE_CODE 70
    21 #define LAST_CODE (BASE_CODE + 15)
    22 #define OUTPUT_BLOCK_SIZE 16
     10
    2311#include <unistd.h>
    2412#include <sys/types.h>
     13#include <zephyr/zephyr.h>
     14#include <glib.h>
     15#include <string.h>
     16#include <stdlib.h>
     17#include <sys/wait.h>
     18#include <ctype.h>
    2519
    2620#ifdef HAVE_KERBEROS_IV
     
    3024#endif
    3125
    32 #define MAX_KEY 128
     26#include "filterproc.h"
     27
     28#define MAX_KEY      128
     29#define MAX_LINE     128
     30#define MAX_RESULT   4096
     31
     32#ifndef TRUE
     33#define TRUE -1
     34#endif
     35#ifndef FALSE
     36#define FALSE 0
     37#endif
    3338
    3439#define ZWRITE_OPT_NOAUTH     (1<<0)
     
    4853
    4954char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance);
     55int ParseCryptSpec(const char *spec, const char **keyfile);
     56char *BuildArgString(char **argv, int start, int end);
     57char *read_keystring(const char *keyfile);
     58
     59int do_encrypt(int zephyr, const char *class, const char *instance,
     60               ZWRITEOPTIONS *zoptions, const char* keyfile, int cipher);
     61int do_encrypt_des(const char *keyfile, const char *in, int len, FILE *out);
     62int do_encrypt_aes(const char *keyfile, const char *in, int len, FILE *out);
     63
     64int do_decrypt(const char *keyfile, int cipher);
     65int do_decrypt_aes(const char *keyfile);
     66int do_decrypt_des(const char *keyfile);
     67
    5068
    5169#define M_NONE            0
     
    5674#define M_SETKEY          5
    5775
    58 static void owl_zcrypt_string_to_schedule(const char *keystring, des_key_schedule *schedule) {
     76enum cipher_algo {
     77  CIPHER_DES,
     78  CIPHER_AES,
     79  NCIPHER
     80};
     81
     82typedef struct {
     83  int (*encrypt)(const char *keyfile, const char *in, int len, FILE *out);
     84  int (*decrypt)(const char *keyfile);
     85} cipher_pair;
     86
     87cipher_pair ciphers[NCIPHER] = {
     88  [CIPHER_DES] { do_encrypt_des, do_decrypt_des},
     89  [CIPHER_AES] { do_encrypt_aes, do_decrypt_aes},
     90};
     91
     92static void owl_zcrypt_string_to_schedule(char *keystring, des_key_schedule *schedule) {
    5993#ifdef HAVE_KERBEROS_IV
    6094  des_cblock key;
     
    67101}
    68102
    69 /* The 'owl_zcrypt_decrypt' function was written by kretch for Owl.
    70  * Decrypt the message in 'in' on class 'class' and instance
    71  * 'instance'.  Return must be freed by caller.
    72  */
    73 char *owl_zcrypt_decrypt(const char *in, const char *class, const char *instance)
    74 {
    75   char *fname, keystring[MAX_KEY];
    76   FILE *fkey;
    77  
    78   fname=GetZephyrVarKeyFile("zcrypt", class, instance);
    79   if (!fname) return NULL;
    80   fkey=fopen(fname, "r");
    81   owl_free(fname);
    82   if (!fkey) return NULL;
    83   if (!fgets(keystring, MAX_KEY-1, fkey)) {
    84     fclose(fkey);
    85     return NULL;
    86   }
    87   fclose(fkey);
    88 
    89   return owl_zcrypt_decrypt_with_key(in, keystring);
    90 }
    91 
    92 char *owl_zcrypt_decrypt_with_key(const char *in, const char *keystring)
    93 {
    94   const char *inptr, *endptr;
    95   char *out;
    96   des_key_schedule schedule;
    97   unsigned char input[8], output[8];
    98   int i, c1, c2;
    99 
    100   /* We read in some number of full 16-byte blocks and write out the
    101    * same number of 8-byte blocks, plus a null terminator.
    102    */
    103   out = owl_malloc((strlen(in) / 16) * 8 + 1);
    104 
    105   strcpy(out, "");
    106 
    107   output[0] = '\0';    /* In case no message at all                 */
    108 
    109   owl_zcrypt_string_to_schedule(keystring, &schedule);
    110 
    111   inptr=in;
    112   endptr = in + strlen(in);
    113   while (inptr + 16 <= endptr) {
    114     for (i=0; i<8; i++) {
    115       c1=(inptr[0])-BASE_CODE;
    116       c2=(inptr[1])-BASE_CODE;
    117       input[i]=c1 * 0x10 + c2;
    118       inptr+=2;
    119     }
    120     des_ecb_encrypt(&input, &output, schedule, FALSE);
    121     strncat(out, (const char *)output, 8);
    122   }
    123 
    124   return out;
    125 }
    126 
    127 char *owl_zcrypt_encrypt(const char *in, const char *class, const char *instance)
    128 {
    129   char *fname, keystring[MAX_KEY];
    130   FILE *fkey;
    131 
    132   fname=GetZephyrVarKeyFile("zcrypt", class, instance);
    133   if (!fname) return NULL;
    134   fkey=fopen(fname, "r");
    135   owl_free(fname);
    136   if (!fkey) return NULL;
    137   if (!fgets(keystring, MAX_KEY-1, fkey)) {
    138     fclose(fkey);
    139     return NULL;
    140   }
    141   fclose(fkey);
    142 
    143   return owl_zcrypt_encrypt_with_key(in, keystring);
    144 }
    145 
    146 char *owl_zcrypt_encrypt_with_key(const char *in, const char *keystring)
    147 {
    148   des_key_schedule schedule;
    149   char *out;
    150   unsigned char input[8], output[8];
    151   int size, length, i;
    152   const char *inbuff = NULL, *inptr;
    153   int num_blocks=0, last_block_size=0;
    154 
    155   owl_zcrypt_string_to_schedule(keystring, &schedule);
    156 
    157   /* Allocate enough space for the crypted message. For each byte of
    158    * the message, the encoded cyphertext will have two bytes. Block
    159    * size is 8 bytes of input, or 16 bytes of output, so make sure we
    160    * have at least one block worth of space allocated. If the message
    161    * is empty, no blocks are sent, but we still allocate one
    162    * block. The additional 16 bytes also provide space for the null
    163    * terminator, as we will never use all of it for cyphertext.
    164    */
    165   out = owl_malloc((strlen(in) * 2) + 16);
    166 
    167   inbuff=in;
    168   length=strlen(inbuff);
    169   num_blocks=(length+7)/8;
    170   last_block_size=((length+7)%8)+1;
    171 
    172   strcpy(out, "");
    173  
    174   inptr=inbuff;
    175   while (TRUE) {
    176     /* Get 8 bytes from buffer */
    177     if (num_blocks > 1) {
    178       size = 8;
    179       memcpy(input, inptr, size);
    180       inptr+=8;
    181       num_blocks--;
    182     } else if (num_blocks == 1) {
    183       size=last_block_size;
    184       memcpy(input, inptr, size);
    185       num_blocks--;
    186     } else {
    187       size=0;
    188     }
    189 
    190     /* Check for EOF and pad the string to 8 chars, if needed */
    191     if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
    192      
    193     if (size<8) memset(input + size, 0, 8 - size);
    194 
    195     /* Encrypt and output the block */
    196     des_ecb_encrypt(&input, &output, schedule, TRUE);
    197 
    198     for (i = 0; i < 8; i++) {
    199       sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE);
    200       sprintf(out + strlen(out), "%c", (output[i] & 0x0f)        + BASE_CODE);
    201     }
    202 
    203     if (size < 8) break;
    204   }
    205   return out;
    206 }
    207 
     103int main(int argc, char *argv[])
     104{
     105  char *cryptspec = NULL;
     106  const char *keyfile;
     107  int cipher;
     108  int error = FALSE;
     109  int zephyr = FALSE;
     110  char *class = NULL, *instance = NULL;
     111  int mode = M_NONE;
     112
     113  extern int optind, opterr;
     114  extern char *optarg;
     115  char c;
     116
     117  int messageflag = FALSE;
     118  ZWRITEOPTIONS zoptions;
     119  zoptions.flags = 0;
     120
     121  while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF)
     122  {
     123    switch(c)
     124    {
     125      case 'Z':
     126        /* Zephyr encrypt */
     127        mode = M_ZEPHYR_ENCRYPT;
     128        break;
     129      case 'D':
     130        /* Decrypt */
     131        mode = M_DECRYPT;
     132        break;
     133      case 'E':
     134        /* Encrypt */
     135        mode = M_ENCRYPT;
     136        break;
     137      case 'R':
     138        /* Randomize the keyfile */
     139        mode = M_RANDOMIZE;
     140        break;
     141      case 'S':
     142        /* Set a new key value from stdin */
     143        mode = M_SETKEY;
     144        break;
     145      case 'F':
     146        /* Specify the keyfile explicitly */
     147        if (cryptspec != NULL) error = TRUE;
     148        cryptspec = optarg;
     149        break;
     150      case 'c':
     151        /* Zwrite/zcrypt: class name */
     152        if (class != NULL) error = TRUE;
     153        class = optarg;
     154        break;
     155      case 'i':
     156        /* Zwrite/zcrypt: instance name */
     157        if (instance != NULL) error = TRUE;
     158        instance = optarg;
     159        break;
     160      case 'a':
     161        /* Zwrite: authenticate (default) */
     162        zoptions.flags &= ~ZWRITE_OPT_NOAUTH;
     163        break;
     164      case 'd':
     165        /* Zwrite: do not authenticate */
     166        zoptions.flags |= ZWRITE_OPT_NOAUTH;
     167        break;
     168      case 'v':
     169        /* Zwrite: verbose */
     170        zoptions.flags |= ZWRITE_OPT_VERBOSE;
     171        break;
     172      case 'q':
     173        /* Zwrite: quiet */
     174        zoptions.flags |= ZWRITE_OPT_QUIET;
     175        break;
     176      case 't':
     177        /* Zwrite: no expand tabs (ignored) */
     178        break;
     179      case 'l':
     180        /* Zwrite: ignore '.' on a line by itself (ignored) */
     181        zoptions.flags |= ZCRYPT_OPT_IGNOREDOT;
     182        break;
     183      case 'u':
     184        /* Zwrite: urgent message */
     185        instance = "URGENT";
     186        break;
     187      case 'o':
     188        /* Zwrite: ignore zephyr variables zwrite-class, zwrite-inst, */
     189        /*         zwrite-opcode */
     190        zoptions.flags |= ZWRITE_OPT_IGNOREVARS;
     191        break;
     192      case 'n':
     193        /* Zwrite: prevent PING message (always used) */
     194        break;
     195      case 's':
     196        /* Zwrite: signature */
     197        zoptions.flags |= ZWRITE_OPT_SIGNATURE;
     198        zoptions.signature = optarg;
     199        break;
     200      case 'f':
     201        /* Zwrite: file system specification (ignored) */
     202        break;
     203      case 'm':
     204        /* Message on rest of line*/
     205        messageflag = TRUE;
     206        break;
     207      case '?':
     208        error = TRUE;
     209        break;
     210    }
     211    if (error || messageflag)
     212      break;
     213  }
     214
     215  if (class != NULL || instance != NULL)
     216    zephyr = TRUE;
     217
     218  if (messageflag)
     219  {
     220    zoptions.flags |= ZCRYPT_OPT_MESSAGE;
     221    zoptions.message = BuildArgString(argv, optind, argc);
     222    if (!zoptions.message)
     223    {
     224      fprintf(stderr, "Memory allocation error.\n");
     225      error = TRUE;
     226    }
     227  }
     228  else if (optind < argc)
     229  {
     230    error = TRUE;
     231  }
     232
     233  if (mode == M_NONE)
     234    mode = (zephyr?M_ZEPHYR_ENCRYPT:M_ENCRYPT);
     235
     236  if (mode == M_ZEPHYR_ENCRYPT && !zephyr)
     237    error = TRUE;
     238
     239  if (!error && cryptspec == NULL && (class != NULL || instance != NULL)) {
     240    cryptspec = GetZephyrVarKeyFile(argv[0], class, instance);
     241    if(!cryptspec) {
     242      fprintf(stderr, "Unable to find keyfile for ");
     243      if(class != NULL) {
     244        fprintf(stderr, "-c %s ", class);
     245      }
     246      if(instance != NULL) {
     247        fprintf(stderr, "-i %s ", instance);
     248      }
     249      fprintf(stderr, "\n");
     250      exit(-1);
     251    }
     252  }
     253
     254  if (error)
     255  {
     256    fprintf(stderr, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]);
     257    fprintf(stderr, "       [-advqtluon] [-s signature] [-f arg] [-m message]\n");
     258    fprintf(stderr, "  One or more of class, instance, and keyfile must be specified.\n");
     259    exit(1);
     260  }
     261
     262  cipher = ParseCryptSpec(cryptspec, &keyfile);
     263  if(cipher < 0) {
     264    fprintf(stderr, "Invalid cipher specification: %s\n", cryptspec);
     265    exit(1);
     266  }
     267
     268
     269  if (mode == M_RANDOMIZE)
     270  {
     271    /* Choose a new, random key */
     272    /*
     273      FILE *fkey = fopen(fname, "w");
     274      if (!fkey)
     275      printf("Could not open key file for writing: %s\n", fname);
     276      else
     277      {
     278      char string[100];
     279      fputs(fkey, string);
     280      fclose(fkey);
     281      }
     282    */
     283    fprintf(stderr, "Feature not yet implemented.\n");
     284  }
     285  else if (mode == M_SETKEY)
     286  {
     287    /* Set a new, user-entered key */
     288    char newkey[MAX_KEY];
     289    FILE *fkey;
     290
     291    if (isatty(0))
     292    {
     293      printf("Enter new key: ");
     294      /* Really should read without echo!!! */
     295    }
     296    if(!fgets(newkey, MAX_KEY - 1, stdin)) {
     297      fprintf(stderr, "Error reading key.\n");
     298      return 1;
     299    }
     300
     301    fkey = fopen(keyfile, "w");
     302    if (!fkey)
     303      fprintf(stderr, "Could not open key file for writing: %s\n", keyfile);
     304    else
     305    {
     306      if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n')
     307      {
     308        fprintf(stderr, "Error writing to key file.\n");
     309        fclose(fkey);
     310        exit(1);
     311      }
     312      else
     313      {
     314        fclose(fkey);
     315        fprintf(stderr, "Key update complete.\n");
     316      }
     317    }
     318  }
     319  else
     320  {
     321    if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT)
     322      error = !do_encrypt((mode == M_ZEPHYR_ENCRYPT), class, instance,
     323                          &zoptions, keyfile, cipher);
     324    else
     325      error = !do_decrypt(keyfile, cipher);
     326  }
     327
     328  /* Always print the **END** message if -D is specified. */
     329  if (mode == M_DECRYPT)
     330    printf("**END**\n");
     331
     332  return error;
     333}
     334
     335int ParseCryptSpec(const char *spec, const char **keyfile) {
     336  int cipher = CIPHER_DES;
     337  char *cipher_name = strdup(spec);
     338  char *colon = strchr(cipher_name, ':');
     339
     340  *keyfile = spec;
     341
     342  if (colon) {
     343    char *rest = strchr(spec, ':') + 1;
     344    while(isspace(*rest)) rest++;
     345
     346    *colon-- = '\0';
     347    while (colon >= cipher_name && isspace(*colon)) {
     348      *colon = '\0';
     349    }
     350
     351    if(strcmp(cipher_name, "AES") == 0) {
     352      cipher = CIPHER_AES;
     353      *keyfile = rest;
     354    } else if(strcmp(cipher_name, "DES") == 0) {
     355      cipher = CIPHER_DES;
     356      *keyfile = rest;
     357    }
     358  }
     359
     360  free(cipher_name);
     361
     362  return cipher;
     363}
     364
     365/* Build a space-separated string from argv from elements between start  *
     366 * and end - 1.  malloc()'s the returned string. */
     367char *BuildArgString(char **argv, int start, int end)
     368{
     369  int len = 1;
     370  int i;
     371  char *result;
     372
     373  /* Compute the length of the string.  (Plus 1 or 2) */
     374  for (i = start; i < end; i++)
     375    len += strlen(argv[i]) + 1;
     376
     377  /* Allocate memory */
     378  result = (char *)malloc(len);
     379  if (result)
     380  {
     381    /* Build the string */
     382    char *ptr = result;
     383    /* Start with an empty string, in case nothing is copied. */
     384    *ptr = '\0';
     385    /* Copy the arguments */
     386    for (i = start; i < end; i++)
     387    {
     388      char *temp = argv[i];
     389      /* Add a space, if not the first argument */
     390      if (i != start)
     391        *ptr++ = ' ';
     392      /* Copy argv[i], leaving ptr pointing to the '\0' copied from temp */
     393      while ((*ptr = *temp++))
     394        ptr++;
     395    }
     396  }
     397
     398  return result;
     399}
    208400
    209401#define MAX_BUFF 258
    210402#define MAX_SEARCH 3
    211403/* Find the class/instance in the .crypt-table */
    212 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance) {
     404char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance)
     405{
    213406  char *keyfile = NULL;
    214407  char *varname[MAX_SEARCH];
     
    223416
    224417  /* Determine names to look for in .crypt-table */
    225   if (instance) {
    226     varname[numsearch++] = owl_sprintf("crypt-%s-%s:", (class?class:"message"), instance);
    227   }
    228   if (class) {
    229     varname[numsearch++] = owl_sprintf("crypt-%s:", class);
    230   }
    231   varname[numsearch++] = owl_strdup("crypt-default:");
     418  if (instance)
     419    varname[numsearch++] = g_strdup_printf("crypt-%s-%s:", (class?class:"message"), instance);
     420  if (class)
     421    varname[numsearch++] = g_strdup_printf("crypt-%s:", class);
     422  varname[numsearch++] = g_strdup("crypt-default:");
    232423
    233424  /* Setup the result array, and determine string lengths */
    234   for (i = 0; i < numsearch; i++) {
     425  for (i = 0; i < numsearch; i++)
     426  {
    235427    result[i][0] = '\0';
    236428    length[i] = strlen(varname[i]);
     
    238430
    239431  /* Open~/.crypt-table */
    240   filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));
     432  filename = g_strdup_printf("%s/.crypt-table", getenv("HOME"));
    241433  fsearch = fopen(filename, "r");
    242   if (fsearch) {
     434  if (fsearch)
     435  {
    243436    /* Scan file for a match */
    244     while (!feof(fsearch)) {
     437    while (!feof(fsearch))
     438    {
    245439      if (!fgets(buffer, MAX_BUFF - 3, fsearch)) break;
    246       for (i = 0; i < numsearch; i++) {
    247         if (strncasecmp(varname[i], buffer, length[i]) == 0) {
    248           int j;
    249           for (j = length[i]; buffer[j] == ' '; j++)
    250             ;
    251           strcpy(result[i], &buffer[j]);
    252           if (*result[i]) {
    253             if (result[i][strlen(result[i])-1] == '\n') {
    254               result[i][strlen(result[i])-1] = '\0';
    255             }
    256           }
    257         }
    258       }
     440      for (i = 0; i < numsearch; i++)
     441        if (strncasecmp(varname[i], buffer, length[i]) == 0)
     442        {
     443          int j;
     444          for (j = length[i]; buffer[j] == ' '; j++)
     445            ;
     446          strcpy(result[i], &buffer[j]);
     447          if (*result[i])
     448            if (result[i][strlen(result[i])-1] == '\n')
     449              result[i][strlen(result[i])-1] = '\0';
     450        }
    259451    }
    260452
    261453    /* Pick the "best" match found */
    262454    keyfile = NULL;
    263     for (i = 0; i < numsearch; i++) {
    264       if (*result[i]) {
    265         keyfile = result[i];
    266         break;
     455    for (i = 0; i < numsearch; i++)
     456      if (*result[i])
     457      {
     458        keyfile = result[i];
     459        break;
    267460      }
    268     }
    269 
    270     if (keyfile == NULL) {
    271       /* printf("Could not find key table entry.\n"); */
     461
     462    if (keyfile != NULL)
     463    {
     464      /* Prepare result to be returned */
     465      char *temp = keyfile;
     466      keyfile = (char *)malloc(strlen(temp) + 1);
     467      if (keyfile)
     468        strcpy(keyfile, temp);
     469      else
     470        fprintf(stderr, "Memory allocation error.\n");
     471    }
     472    fclose(fsearch);
     473  }
     474  else
     475    fprintf(stderr, "Could not open key table file: %s\n", filename);
     476
     477  for(i = 0; i < MAX_SEARCH; i++) {
     478    if(varname[i] != NULL) {
     479      g_free(varname[i]);
     480    }
     481  }
     482
     483  if(filename != NULL) {
     484    g_free(filename);
     485  }
     486
     487  return keyfile;
     488}
     489
     490static pid_t zephyrpipe_pid = 0;
     491
     492/* Open a pipe to zwrite */
     493FILE *GetZephyrPipe(const char *class, const char *instance, const ZWRITEOPTIONS *zoptions)
     494{
     495  int fildes[2];
     496  pid_t pid;
     497  FILE *result;
     498  const char *argv[20];
     499  int argc = 0;
     500
     501  if (pipe(fildes) < 0)
     502    return NULL;
     503  pid = fork();
     504
     505  if (pid < 0)
     506  {
     507    /* Error: clean up */
     508    close(fildes[0]);
     509    close(fildes[1]);
     510    result = NULL;
     511  }
     512  else if (pid == 0)
     513  {
     514    /* Setup child process */
     515    argv[argc++] = "zwrite";
     516    argv[argc++] = "-n";     /* Always send without ping */
     517    if (class)
     518    {
     519      argv[argc++] = "-c";
     520      argv[argc++] = class;
     521    }
     522    if (instance)
     523    {
     524      argv[argc++] = "-i";
     525      argv[argc++] = instance;
     526    }
     527    if (zoptions->flags & ZWRITE_OPT_NOAUTH)
     528      argv[argc++] = "-d";
     529    if (zoptions->flags & ZWRITE_OPT_QUIET)
     530      argv[argc++] = "-q";
     531    if (zoptions->flags & ZWRITE_OPT_VERBOSE)
     532      argv[argc++] = "-v";
     533    if (zoptions->flags & ZWRITE_OPT_SIGNATURE)
     534    {
     535      argv[argc++] = "-s";
     536      argv[argc++] = zoptions->signature;
     537    }
     538    argv[argc++] = "-O";
     539    argv[argc++] = "crypt";
     540    argv[argc] = NULL;
     541    close(fildes[1]);
     542    if (fildes[0] != STDIN_FILENO)
     543    {
     544      if (dup2(fildes[0], STDIN_FILENO) != STDIN_FILENO)
     545        exit(0);
     546      close(fildes[0]);
     547    }
     548    close(fildes[0]);
     549    execvp(argv[0], (char **)argv);
     550    fprintf(stderr, "Exec error: could not run zwrite\n");
     551    exit(0);
     552  }
     553  else
     554  {
     555    close(fildes[0]);
     556    /* Create a FILE * for the zwrite pipe */
     557    result = (FILE *)fdopen(fildes[1], "w");
     558    zephyrpipe_pid = pid;
     559  }
     560
     561  return result;
     562}
     563
     564/* Close the pipe to zwrite */
     565void CloseZephyrPipe(FILE *pipe)
     566{
     567  fclose(pipe);
     568  waitpid(zephyrpipe_pid, NULL, 0);
     569  zephyrpipe_pid = 0;
     570}
     571
     572#define BASE_CODE 70
     573#define LAST_CODE (BASE_CODE + 15)
     574#define OUTPUT_BLOCK_SIZE 16
     575
     576void block_to_ascii(unsigned char *output, FILE *outfile)
     577{
     578  int i;
     579  for (i = 0; i < 8; i++)
     580  {
     581    putc(((output[i] & 0xf0) >> 4) + BASE_CODE, outfile);
     582    putc( (output[i] & 0x0f)       + BASE_CODE, outfile);
     583  }
     584}
     585
     586char *slurp_stdin(int ignoredot, int *length) {
     587  char *buf;
     588  char *inptr;
     589
     590  if ((inptr = buf = (char *)malloc(MAX_RESULT)) == NULL)
     591  {
     592    fprintf(stderr, "Memory allocation error\n");
     593    return NULL;
     594  }
     595  while (inptr - buf < MAX_RESULT - MAX_LINE - 20)
     596  {
     597    if (fgets(inptr, MAX_LINE, stdin) == NULL)
     598      break;
     599
     600    if (inptr[0])
     601    {
     602      if (inptr[0] == '.' && inptr[1] == '\n' && !ignoredot)
     603      {
     604        inptr[0] = '\0';
     605        break;
     606      }
     607      else
     608        inptr += strlen(inptr);
     609    }
     610    else
     611      break;
     612  }
     613  *length = inptr - buf;
     614
     615  return buf;
     616}
     617
     618char *GetInputBuffer(ZWRITEOPTIONS *zoptions, int *length) {
     619  char *buf;
     620
     621  if (zoptions->flags & ZCRYPT_OPT_MESSAGE)
     622  {
     623    /* Use the -m message */
     624    buf = strdup(zoptions->message);
     625    *length = strlen(buf);
     626  }
     627  else
     628  {
     629    if (isatty(0)) {
     630      /* tty input, so show the "Type your message now..." message */
     631      if (zoptions->flags & ZCRYPT_OPT_IGNOREDOT)
     632        printf("Type your message now.  End with the end-of-file character.\n");
     633      else
     634        printf("Type your message now.  End with control-D or a dot on a line by itself.\n");
    272635    } else {
    273       /* Prepare result to be returned */
    274       keyfile = owl_strdup(keyfile);
    275     }
    276    
    277     fclose(fsearch);
    278   } else {
    279     /* printf("Could not open key table file: %s\n", filename); */
    280   }
    281 
    282   for(i = 0; i < MAX_SEARCH; i++) {
    283     owl_free(varname[i]);
    284   }
    285 
    286   owl_free(filename);
    287 
    288   return(keyfile);
    289 }
    290 
    291 #endif
     636      zoptions->flags |= ZCRYPT_OPT_IGNOREDOT;
     637    }
     638
     639    buf = slurp_stdin(zoptions->flags & ZCRYPT_OPT_IGNOREDOT, length);
     640  }
     641  return buf;
     642}
     643
     644char *read_keystring(const char *keyfile) {
     645  char *keystring;
     646  FILE *fkey = fopen(keyfile, "r");
     647  if(!fkey) {
     648    fprintf(stderr, "Unable to open keyfile %s\n", keyfile);
     649    return NULL;
     650  }
     651  keystring = malloc(MAX_KEY);
     652  if(!fgets(keystring, MAX_KEY-1, fkey)) {
     653    fprintf(stderr, "Unable to read from keyfile: %s\n", keyfile);
     654    free(keystring);
     655    keystring = NULL;
     656  }
     657  fclose(fkey);
     658  return keystring;
     659}
     660
     661/* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite
     662   if zephyr is set. */
     663int do_encrypt(int zephyr, const char *class, const char *instance,
     664               ZWRITEOPTIONS *zoptions, const char *keyfile, int cipher)
     665{
     666  FILE *outfile = stdout;
     667  char *inbuff = NULL;
     668  int buflen;
     669  int out = TRUE;
     670
     671  inbuff = GetInputBuffer(zoptions, &buflen);
     672
     673  if(!inbuff) {
     674    fprintf(stderr, "Error reading zcrypt input!\n");
     675    return FALSE;
     676  }
     677
     678  if (zephyr) {
     679    outfile = GetZephyrPipe(class, instance, zoptions);
     680    if (!outfile)
     681    {
     682      fprintf(stderr, "Could not run zwrite\n");
     683      if (inbuff)
     684        free(inbuff);
     685      return FALSE;
     686    }
     687  }
     688
     689  out = ciphers[cipher].encrypt(keyfile, inbuff, buflen, outfile);
     690
     691  if (zephyr)
     692    CloseZephyrPipe(outfile);
     693
     694  free(inbuff);
     695  return out;
     696}
     697
     698int do_encrypt_des(const char *keyfile, const char *in, int length, FILE *outfile)
     699{
     700  des_key_schedule schedule;
     701  unsigned char input[8], output[8];
     702  const char *inptr;
     703  int num_blocks, last_block_size;
     704  char *keystring;
     705  int size;
     706
     707  keystring = read_keystring(keyfile);
     708  if(!keystring) {
     709    return FALSE;
     710  }
     711
     712  owl_zcrypt_string_to_schedule(keystring, &schedule);
     713  free(keystring);
     714
     715  inptr = in;
     716  num_blocks = (length + 7) / 8;
     717  last_block_size = ((length + 7) % 8) + 1;
     718
     719  /* Encrypt the input (inbuff or stdin) and send it to outfile */
     720  while (TRUE)
     721  {
     722    /* Get 8 bytes from buffer */
     723    if (num_blocks > 1)
     724    {
     725      size = 8;
     726      memcpy(input, inptr, size);
     727      inptr += 8;
     728      num_blocks--;
     729    }
     730    else if (num_blocks == 1)
     731    {
     732      size = last_block_size;
     733      memcpy(input, inptr, size);
     734      num_blocks--;
     735    }
     736    else
     737      size = 0;
     738
     739    /* Check for EOF and pad the string to 8 chars, if needed */
     740    if (size == 0)
     741      break;
     742    if (size < 8)
     743      memset(input + size, 0, 8 - size);
     744
     745    /* Encrypt and output the block */
     746    des_ecb_encrypt(&input, &output, schedule, TRUE);
     747    block_to_ascii(output, outfile);
     748
     749    if (size < 8)
     750      break;
     751  }
     752
     753  putc('\n', outfile);
     754
     755  return TRUE;
     756}
     757
     758int do_encrypt_aes(const char *keyfile, const char *in, int length, FILE *outfile)
     759{
     760  char *out;
     761  int err, status;
     762  const char *argv[] = {
     763    "gpg",
     764    "--symmetric",
     765    "--batch",
     766    "--quiet",
     767    "--no-use-agent",
     768    "--armor",
     769    "--cipher-algo", "AES",
     770    "--passphrase-file", keyfile,
     771    NULL
     772  };
     773  err = call_filter("gpg", argv, in, &out, &status);
     774  if(err || status) {
     775    if(out) g_free(out);
     776    return FALSE;
     777  }
     778  fwrite(out, strlen(out), 1, outfile);
     779  g_free(out);
     780  return TRUE;
     781}
     782
     783/* Read a half-byte from stdin, skipping invalid characters.  Returns -1
     784   if at EOF or file error */
     785int read_ascii_nybble(void)
     786{
     787  char c;
     788
     789  while (TRUE)
     790  {
     791    if (fread(&c, 1, 1, stdin) == 0)
     792      return -1;
     793    else if (c >= BASE_CODE && c <= LAST_CODE)
     794      return c - BASE_CODE;
     795  }
     796}
     797
     798/* Read both halves of the byte and return the single byte.  Returns -1
     799   if at EOF or file error. */
     800int read_ascii_byte(void)
     801{
     802  int c1, c2;
     803  c1 = read_ascii_nybble();
     804  if (c1 >= 0)
     805  {
     806    c2 = read_ascii_nybble();
     807    if (c2 >= 0)
     808    {
     809      return c1 * 0x10 + c2;
     810    }
     811  }
     812  return -1;
     813}
     814
     815/* Read an 8-byte DES block from stdin */
     816int read_ascii_block(unsigned char *input)
     817{
     818  int c;
     819
     820  int i;
     821  for (i = 0; i < 8; i++)
     822  {
     823    c = read_ascii_byte();
     824    if (c < 0)
     825      return FALSE;
     826
     827    input[i] = c;
     828  }
     829
     830  return TRUE;
     831}
     832
     833/* Decrypt stdin */
     834int do_decrypt(const char *keyfile, int cipher)
     835{
     836  return ciphers[cipher].decrypt(keyfile);
     837}
     838
     839int do_decrypt_aes(const char *keyfile) {
     840  char *in, *out;
     841  int length;
     842  const char *argv[] = {
     843    "gpg",
     844    "--decrypt",
     845    "--batch",
     846    "--no-use-agent",
     847    "--quiet",
     848    "--passphrase-file", keyfile,
     849    NULL
     850  };
     851  int err, status;
     852
     853  in = slurp_stdin(TRUE, &length);
     854  if(!in) return FALSE;
     855
     856  err = call_filter("gpg", argv, in, &out, &status);
     857  if(err || status) {
     858    if(out) g_free(out);
     859    return FALSE;
     860  }
     861  fwrite(out, strlen(out), 1, stdout);
     862  g_free(out);
     863
     864  return TRUE;
     865}
     866
     867int do_decrypt_des(const char *keyfile) {
     868  des_key_schedule schedule;
     869  unsigned char input[8], output[8];
     870  char *keystring;
     871
     872  output[0] = '\0';    /* In case no message at all                 */
     873
     874  keystring = read_keystring(keyfile);
     875  if(!keystring) return FALSE;
     876
     877  owl_zcrypt_string_to_schedule(keystring, &schedule);
     878
     879  free(keystring);
     880
     881  while (read_ascii_block(input))
     882  {
     883    des_ecb_encrypt(&input, &output, schedule, FALSE);
     884    printf("%s", output);
     885  }
     886
     887  if (!output[0] || output[strlen((const char*)output) - 1] != '\n')
     888      printf("\n");
     889  return TRUE;
     890}
  • editwin.c

    rf449096 r21dd391  
    3535  oe_excursion *excursions;
    3636
    37   char *command;
    3837  void (*callback)(struct _owl_editwin*);
     38  void (*destroy_cbdata)(void *);
    3939  void *cbdata;
    4040};
     
    4545static void oe_restore_excursion(owl_editwin *e, oe_excursion *x);
    4646static void oe_restore_mark_only(owl_editwin *e, oe_excursion *x);
    47 static int oe_count_glyphs(const char *s);
    4847static int oe_char_width(gunichar c, int column);
    4948static int oe_region_width(owl_editwin *e, int start, int end, int width);
     
    5857static int oe_copy_region(owl_editwin *e);
    5958static char *oe_chunk(owl_editwin *e, int start, int end);
     59static void oe_destroy_cbdata(owl_editwin *e);
    6060
    6161#define INCR 4096
     
    6363#define WHITESPACE " \n\t"
    6464
    65 owl_editwin *owl_editwin_allocate(void)
     65static owl_editwin *owl_editwin_allocate(void)
    6666{
    6767  owl_editwin *e;
     
    7575  owl_free(e->buff);
    7676  owl_free(e->killbuf);
    77   owl_free(e->command);
    7877  /* just in case someone forgot to clean up */
    7978  while (e->excursions) {
    8079    oe_release_excursion(e, e->excursions);
    8180  }
     81  oe_destroy_cbdata(e);
    8282
    8383  owl_free(e);
    84 }
    85 
    86 static int oe_count_glyphs(const char *s)
    87 {
    88   int count = 0;
    89   const char *p;
    90 
    91   for(p = s; *p != 0; p = g_utf8_find_next_char(p, NULL))
    92     if (!g_unichar_ismark(g_utf8_get_char(p)))
    93       count++;
    94 
    95   return count;
    9684}
    9785
     
    116104}
    117105
    118 /* initialize the editwin e.
    119  * 'win' is an already initialzed curses window that will be used by editwin
    120  */
    121 void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
     106static void _owl_editwin_init(owl_editwin *e,
     107                              WINDOW *win,
     108                              int winlines,
     109                              int wincols,
     110                              int style,
     111                              owl_history *hist)
    122112{
    123113  e->buff=owl_malloc(INCR);
     
    145135  e->echochar='\0';
    146136
    147   /* We get initialized multiple times, but we need to hold on to
    148      the callbacks, so we can't NULL them here. */
    149   /*
    150     e->command = NULL;
    151     e->callback = NULL;
    152     e->cbdata = NULL;
    153   */
    154137  if (win) werase(win);
     138}
     139
     140owl_editwin *owl_editwin_new(WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
     141{
     142  owl_editwin *e = owl_editwin_allocate();
     143
     144  _owl_editwin_init(e, win, winlines, wincols, style, hist);
     145  return e;
    155146}
    156147
     
    188179}
    189180
    190 void owl_editwin_set_command(owl_editwin *e, const char *command)
    191 {
    192   if(e->command) owl_free(e->command);
    193   e->command = owl_strdup(command);
    194 }
    195 
    196 const char *owl_editwin_get_command(owl_editwin *e)
    197 {
    198   if(e->command) return e->command;
    199   return "";
    200 }
    201 
    202181void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*))
    203182{
     
    210189}
    211190
    212 void owl_editwin_set_cbdata(owl_editwin *e, void *data)
    213 {
     191static void oe_destroy_cbdata(owl_editwin *e) {
     192  if (e->destroy_cbdata)
     193    e->destroy_cbdata(e->cbdata);
     194  e->cbdata = NULL;
     195  e->destroy_cbdata = NULL;
     196}
     197
     198void owl_editwin_set_cbdata(owl_editwin *e, void *data, void (*destroy)(void *))
     199{
     200  oe_destroy_cbdata(e);
    214201  e->cbdata = data;
     202  e->destroy_cbdata = destroy;
    215203}
    216204
     
    259247}
    260248
    261 void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h)
    262 {
    263   e->hist = h;
    264 
    265   if (e->style==newstyle) return;
    266 
    267   if (newstyle==OWL_EDITWIN_STYLE_MULTILINE) {
    268     e->style=newstyle;
    269   } else if (newstyle==OWL_EDITWIN_STYLE_ONELINE) {
    270     e->style=newstyle;
    271 
    272     /* nuke everything after the first line */
    273     owl_editwin_move_to_top(e);
    274     owl_editwin_move_to_end_of_line(e);
    275     owl_editwin_replace(e, oe_count_glyphs(e->buff + e->index),  "");
    276   }
    277 }
    278 
    279 /* completly reinitialize the buffer */
    280 void owl_editwin_fullclear(owl_editwin *e)
    281 {
    282   owl_free(e->buff);
    283   owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
    284 }
    285 
    286249/* clear all text except for locktext and put the cursor at the
    287250 * beginning
     
    302265
    303266  owl_free(e->buff);
    304   owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
     267  _owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
    305268
    306269  if (lock > 0) {
  • global.c

    r2ee9e8d r98d296d  
    4545  g->rightshift=0;
    4646
    47   g->tw = owl_editwin_allocate();
    48   owl_editwin_init(g->tw, NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
     47  g->tw = NULL;
    4948
    5049  owl_keyhandler_init(&g->kh);
     
    5857  g->curmsg_vert_offset=0;
    5958  g->resizepending=0;
    60   g->typwinactive=0;
    6159  g->direction=OWL_DIRECTION_DOWNWARDS;
    6260  g->zaway=0;
     
    111109  owl_zbuddylist_create(&(g->zbuddies));
    112110
     111  g->zaldlist = NULL;
     112  g->pseudologin_notify = 0;
     113
    113114  owl_obarray_init(&(g->obarray));
    114115
     
    171172  _owl_panel_set_window(&g->typpan, newwin(typwin_lines, cols, g->recwinlines+2, 0));
    172173
    173   owl_editwin_set_curswin(g->tw, owl_global_get_curs_typwin(g), typwin_lines, g->cols);
     174  if (g->tw)
     175      owl_editwin_set_curswin(g->tw, owl_global_get_curs_typwin(g), typwin_lines, g->cols);
    174176
    175177  idlok(owl_global_get_curs_typwin(g), FALSE);
     
    324326}
    325327
    326 /* buffercommand */
    327 
    328 void owl_global_set_buffercommand(owl_global *g, const char *command) {
    329   owl_editwin_set_command(owl_global_get_typwin(g), command);
    330 }
    331 
    332 const char *owl_global_get_buffercommand(const owl_global *g) {
    333   return owl_editwin_get_command(owl_global_get_typwin(g));
    334 }
    335 
    336 void owl_global_set_buffercallback(owl_global *g, void (*cb)(owl_editwin*)) {
    337   owl_editwin_set_callback(owl_global_get_typwin(g), cb);
    338 }
    339 
    340 void (*owl_global_get_buffercallback(const owl_global *g))(owl_editwin*) {
    341   return owl_editwin_get_callback(owl_global_get_typwin(g));
    342 }
    343 
    344328/* refresh */
    345329
     
    381365/* typwin */
    382366
    383 int owl_global_is_typwin_active(const owl_global *g) {
    384   if (g->typwinactive==1) return(1);
    385   return(0);
    386 }
    387 
    388 void owl_global_set_typwin_active(owl_global *g) {
    389   int d = owl_global_get_typewindelta(g);
    390   if (d > 0)
     367owl_editwin *owl_global_set_typwin_active(owl_global *g, int style, owl_history *hist) {
     368  int d;
     369  d = owl_global_get_typewindelta(g);
     370  if (d > 0 && style == OWL_EDITWIN_STYLE_MULTILINE)
    391371      owl_function_resize_typwin(owl_global_get_typwin_lines(g) + d);
    392372
    393   g->typwinactive=1;
     373  g->tw = owl_editwin_new(owl_global_get_curs_typwin(g),
     374                          owl_global_get_typwin_lines(g),
     375                          g->cols,
     376                          style,
     377                          hist);
     378  return g->tw;
    394379}
    395380
    396381void owl_global_set_typwin_inactive(owl_global *g) {
    397382  int d = owl_global_get_typewindelta(g);
    398   if (d > 0)
     383  if (d > 0 && owl_editwin_get_style(g->tw) == OWL_EDITWIN_STYLE_MULTILINE)
    399384      owl_function_resize_typwin(owl_global_get_typwin_lines(g) - d);
    400385
    401   g->typwinactive=0;
     386  werase(owl_global_get_curs_typwin(g));
     387  g->tw = NULL;
    402388}
    403389
     
    531517  owl_mainwin_redisplay(&(g->mw));
    532518  sepbar(NULL);
    533   owl_editwin_redisplay(g->tw);
     519  if (g->tw)
     520      owl_editwin_redisplay(g->tw);
     521  else
     522    werase(owl_global_get_curs_typwin(g));
     523
    534524  owl_function_full_redisplay();
    535525
     
    968958}
    969959
     960GList **owl_global_get_zaldlist(owl_global *g)
     961{
     962  return &(g->zaldlist);
     963}
     964
     965int owl_global_get_pseudologin_notify(owl_global *g)
     966{
     967  return g->pseudologin_notify;
     968}
     969
     970void owl_global_set_pseudologin_notify(owl_global *g, int notify)
     971{
     972  g->pseudologin_notify = notify;
     973}
     974
    970975struct termios *owl_global_get_startup_tio(owl_global *g)
    971976{
  • keybinding.c

    r920201c r8a921b5  
    1414int owl_keybinding_init(owl_keybinding *kb, const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
    1515{
    16   char **ktokens;
    17   int    nktokens, i;
    18  
    1916  owl_function_debugmsg("owl_keybinding_init: creating binding for <%s> with desc: <%s>", keyseq, desc);
    2017  if (command && !function_fn) {
     
    2522    return(-1);
    2623  }
     24
     25  if (owl_keybinding_make_keys(kb, keyseq) != 0) {
     26    return(-1);
     27  }
     28
     29  if (command) kb->command = owl_strdup(command);
     30  kb->function_fn = function_fn;
     31  if (desc) kb->desc = owl_strdup(desc);
     32  else kb->desc = NULL;
     33  return(0);
     34}
     35
     36int owl_keybinding_make_keys(owl_keybinding *kb, const char *keyseq)
     37{
     38  char **ktokens;
     39  int    nktokens, i;
    2740
    2841  ktokens = atokenize(keyseq, " ", &nktokens);
     
    4255  }
    4356  kb->len = nktokens;
    44 
    4557  atokenize_delete(ktokens, nktokens);
    46 
    47   if (command) kb->command = owl_strdup(command);
    48   kb->function_fn = function_fn;
    49   if (desc) kb->desc = owl_strdup(desc);
    50   else kb->desc = NULL;
    5158  return(0);
    5259}
  • keymap.c

    rbb0d439 r8a921b5  
    5151  }
    5252  return owl_list_append_element(&km->bindings, kb); 
    53 }
     53
     54}
     55
     56/* removes the binding associated with the keymap */
     57int owl_keymap_remove_binding(owl_keymap *km, const char *keyseq)
     58{
     59  owl_keybinding *kb, *curkb;
     60  int i;
     61
     62  if ((kb = owl_malloc(sizeof(owl_keybinding))) == NULL) return(-1);
     63  if (0 != owl_keybinding_make_keys(kb, keyseq)) {
     64    owl_free(kb);
     65    return(-1);
     66  }
     67
     68  for (i = owl_list_get_size(&km->bindings)-1; i >= 0; i--) {
     69    curkb = owl_list_get_element(&km->bindings, i);
     70    if (owl_keybinding_equal(curkb, kb)) {
     71      owl_list_remove_element(&km->bindings, i);
     72      owl_keybinding_delete(curkb);
     73      return(0);
     74    }
     75  }
     76  return(-2);
     77}
     78
    5479
    5580/* returns a summary line describing this keymap.  the caller must free. */
  • keys.c

    r8830df47 r8a5b5a1  
    246246  BIND_CMD("M-n", "smartnarrow",      "narrow to a view based on the current message");
    247247  BIND_CMD("M-N", "smartnarrow -i",   "narrow to a view based on the current message, and consider instance pair");
     248  BIND_CMD("M-m", "smartnarrow -r",   "like M-n but with 'narrow-related' temporarily flipped.");
     249  BIND_CMD("M-M", "smartnarrow -ri",  "like M-N but with 'narrow-related' temporarily flipped.");
    248250  BIND_CMD("M-p", "view personal", "");
    249251 
  • owl.c

    rf449096 r98d296d  
    629629      /* leave the cursor in the appropriate window */
    630630      if (!owl_popwin_is_active(owl_global_get_popwin(&g))
    631           && owl_global_is_typwin_active(&g)) {
     631          && owl_global_get_typwin(&g)) {
    632632        owl_function_set_cursor(typwin);
    633633      } else {
  • owl.h

    r03c5bdd r98d296d  
    559559  int resizepending;
    560560  int recwinlines;
    561   int typwinactive;
    562561  char *thishost;
    563562  char *homedir;
     
    604603  owl_zbuddylist zbuddies;
    605604  owl_timer zephyr_buddycheck_timer;
     605  GList *zaldlist;
     606  int pseudologin_notify;
    606607  struct termios startup_tio;
    607608  owl_obarray obarray;
  • perl/lib/BarnOwl/Style/Default.pm

    rad0dedd r0fe69d2  
    168168    ? '@color(cyan)' : '';
    169169
    170   my $chars = $oneline ? qr/[[:cntrl:]]/ : qr/[^[:print:]]|[\r\cK\f]/;
     170  my $chars = $oneline ? qr/[[:cntrl:]]/ : qr/[^[:print:]\n]|[\r\cK\f]/;
    171171
    172172  $s =~ s/($chars)/
     
    179179
    180180As above, but always be conservative, and replace with a '?' instead
    181 of something mmore elaborate.
     181of something more elaborate.
    182182
    183183=cut
  • perlconfig.c

    r8f2d9bf r1b1cd2c  
    574574  FREETMPS;
    575575  LEAVE;
    576 
    577   SvREFCNT_dec(cb);
    578   owl_editwin_set_cbdata(e, NULL);
     576}
     577
     578void owl_perlconfig_dec_refcnt(void *data)
     579{
     580  SV *v = data;
     581  SvREFCNT_dec(v);
    579582}
    580583
  • perlglue.xs

    r8c59178 r9186c75  
    172172        SV *callback
    173173        PREINIT:
     174                owl_editwin *e;
    174175        CODE:
    175176        {
     
    177178                        croak("Callback must be a subref");
    178179
    179                 owl_function_start_question(line);
    180 
    181                 owl_editwin_set_cbdata(owl_global_get_typwin(&g), newSVsv(callback));
    182                 owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
     180                e = owl_function_start_question(line);
     181
     182                owl_editwin_set_cbdata(e,
     183                                       newSVsv(callback),
     184                                       owl_perlconfig_dec_refcnt);
     185                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
    183186        }
    184187
     
    188191        SV *callback
    189192        PREINIT:
     193                owl_editwin *e;
    190194        CODE:
    191195        {
     
    193197                        croak("Callback must be a subref");
    194198
    195                 owl_function_start_password(line);
    196 
    197                 owl_editwin_set_cbdata(owl_global_get_typwin(&g), newSVsv(callback));
    198                 owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
     199                e = owl_function_start_password(line);
     200
     201                owl_editwin_set_cbdata(e,
     202                                       newSVsv(callback),
     203                                       owl_perlconfig_dec_refcnt);
     204                owl_editwin_set_callback(e, owl_perlconfig_edit_callback);
    199205        }
    200206
     
    208214                        croak("Callback must be a subref");
    209215
    210                 owl_function_start_edit_win(line, owl_perlconfig_edit_callback, newSVsv(callback));
     216                owl_function_start_edit_win(line,
     217                                            owl_perlconfig_edit_callback,
     218                                            newSVsv(callback),
     219                                            owl_perlconfig_dec_refcnt);
    211220        }
    212221
     
    542551        int count;
    543552        const char *string;
    544         CODE:
    545                 RETVAL = owl_editwin_replace(owl_global_get_typwin(&g), count, string);
     553        PREINIT:
     554                owl_editwin *e;
     555        CODE:
     556                e = owl_global_get_typwin(&g);
     557                if (e) {
     558                        RETVAL = owl_editwin_replace(e, count, string);
     559                } else {
     560                        RETVAL = 0;
     561                }
    546562        OUTPUT:
    547563                RETVAL
     
    550566point_move(delta)
    551567        int delta;
    552         CODE:
    553                 RETVAL = owl_editwin_point_move(owl_global_get_typwin(&g), delta);
     568        PREINIT:
     569                owl_editwin *e;
     570        CODE:
     571                e = owl_global_get_typwin(&g);
     572                if (e) {
     573                        RETVAL = owl_editwin_point_move(e, delta);
     574                } else {
     575                        RETVAL = 0;
     576                }
    554577        OUTPUT:
    555578                RETVAL
     
    558581replace_region(string)
    559582        const char *string;
    560         CODE:
    561                 RETVAL = owl_editwin_replace_region(owl_global_get_typwin(&g), string);
     583        PREINIT:
     584                owl_editwin *e;
     585        CODE:
     586                e = owl_global_get_typwin(&g);
     587                if (e) {
     588                        RETVAL = owl_editwin_replace_region(e, string);
     589                } else {
     590                        RETVAL = 0;
     591                }
    562592        OUTPUT:
    563593                RETVAL
     
    567597        PREINIT:
    568598                char *region;
    569         CODE:
    570                 region = owl_editwin_get_region(owl_global_get_typwin(&g));
     599                owl_editwin *e;
     600        CODE:
     601                e = owl_global_get_typwin(&g);
     602                if (e) {
     603                        region = owl_editwin_get_region(owl_global_get_typwin(&g));
     604                } else {
     605                        region = NULL;
     606                }
    571607                RETVAL = region;
    572608        OUTPUT:
     
    581617        PREINIT:
    582618                int count;
     619                owl_editwin *e;
    583620                owl_editwin_excursion *x;
    584621        CODE:
    585622        {
     623                e = owl_global_get_typwin(&g);
     624                if(!e)
     625                        croak("The edit window is not currently active!");
     626
    586627                x = owl_editwin_begin_excursion(owl_global_get_typwin(&g));
    587628                PUSHMARK(SP);
     
    605646int
    606647current_column()
    607         CODE:
    608                 RETVAL = owl_editwin_current_column(owl_global_get_typwin(&g));
     648        PREINIT:
     649                owl_editwin *e;
     650        CODE:
     651                e = owl_global_get_typwin(&g);
     652                if (e) {
     653                        RETVAL = owl_editwin_current_column(e);
     654                } else {
     655                        RETVAL = 0;
     656                }
    609657        OUTPUT:
    610658                RETVAL
     
    612660int
    613661point()
    614         CODE:
    615                 RETVAL = owl_editwin_get_point(owl_global_get_typwin(&g));
     662        PREINIT:
     663                owl_editwin *e;
     664        CODE:
     665                e = owl_global_get_typwin(&g);
     666                if (e) {
     667                        RETVAL = owl_editwin_get_point(e);
     668                } else {
     669                        RETVAL = 0;
     670                }
    616671        OUTPUT:
    617672                RETVAL
     
    619674int
    620675mark()
    621         CODE:
    622                 RETVAL = owl_editwin_get_mark(owl_global_get_typwin(&g));
    623         OUTPUT:
    624                 RETVAL
     676        PREINIT:
     677                owl_editwin *e;
     678        CODE:
     679                e = owl_global_get_typwin(&g);
     680                if (e) {
     681                        RETVAL = owl_editwin_get_mark(e);
     682                } else {
     683                        RETVAL = 0;
     684                }
     685        OUTPUT:
     686                RETVAL
  • popexec.c

    r4cca591 r125fd21  
    9696  if (!pe->pid && !pe->winactive) {
    9797    owl_select_remove_io_dispatch(d);
     98    pe->dispatch = NULL;
    9899    return;
    99100  }
     
    114115    }
    115116    owl_select_remove_io_dispatch(d);
     117    pe->dispatch = NULL;
    116118    return;
    117119  }
     
    157159
    158160  pe->winactive = 0;
    159   if (pe->dispatch->fd > 0) {
     161  if (pe->dispatch) {
    160162    owl_select_remove_io_dispatch(pe->dispatch);
     163    pe->dispatch = NULL;
    161164  }
    162165  if (pe->pid) {
  • scripts/add-changelog

    r68ab07c r51dbfb5  
    11#!/bin/sh
    22version=$1; shift
     3
     4if [ -z "$version" ] || [ "$#" = 0 ];  then
     5    echo "Usage: $0 VERSION REV-LIST-ARGS" > &2
     6    exit 1;
     7fi
    38
    49(
  • scripts/do-release

    rd771d1b r51dbfb5  
    44    echo "$@" >&2
    55    exit 1
     6}
     7
     8usage() {
     9    cat >&2 <<EOF
     10Usage: %0 [options]
     11Generate a barnowl release tarball.
     12
     13OPTIONS:
     14  -f            Don't require a changelog entry for the new release.
     15  --no-tag      Don't create and sign a git tag for the new release
     16  --git         Do a beta release for the current git revision.
     17EOF
    618}
    719
     
    1527        --no-tag) no_tag=1 ;;
    1628        --git) git=1 ;;
     29        -h|--help) usage ;;
    1730    esac
    1831done
  • scripts/locker-build

    r2b6622a6 r51dbfb5  
    33#########################################################
    44# Build script to build BarnOwl for the locker.
    5 
    6 # Usage: locker-build [-n] [-o OUTPUT-TGZ] SOURCE-TARBALL
    7 # -n is a dry-run, and drops to a shell in the build directory
    8 # -o does the install into a temporary directory and tars it into the
    9 #    specified tarball instead.
    10 # SOURCE-TARBALL is a source tarball, created by do-release
    11 
    125die() {
    136    echo "$@" 2>&1;
     
    2215
    2316usage () {
    24     echo "Usage: $0 [-n] [-o OUTPUT-TGZ] SOURCE-TARBALL"
     17    cat >&2 <<EOF
     18Usage: $0 [-n] [-o OUTPUT-TGZ] SOURCE-TARBALL
     19 -n is a dry-run, and drops to a shell in the build directory
     20 -o does the install into a temporary directory and tars it into the
     21    specified tarball instead.
     22
     23SOURCE-TARBALL is a source tarball, created by do-release.
     24EOF
    2525    exit 2;
    2626}
  • variable.c

    r66a8cd6 r66e409c  
    358358               "normal,top,neartop,center,paged,pagedcenter" ),
    359359
     360  OWLVAR_BOOL( "narrow-related" /* %OwlVarStub:narrow_related */, 1,
     361               "Make smartnarrow use broader filters",
     362               "Causes smartfiler to narrow to messages \"related\" to \n"
     363               "the current message, as well as ones to the same place.\n\n"
     364               "for Zephyr, this controls whether to narrow to e.g. class-help or\n"
     365               "class-help.d alone, or to related-class-help, which includes\n"
     366               "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ),
    360367
    361368  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
  • zephyr.c

    rc230bc1 rf25812b  
    12991299}
    13001300
     1301#ifdef HAVE_LIBZEPHYR
     1302void owl_zephyr_process_pseudologin(ZNotice_t *n)
     1303{
     1304  owl_message *m;
     1305  owl_zbuddylist *zbl;
     1306  GList **zaldlist;
     1307  GList *zaldptr;
     1308  ZAsyncLocateData_t *zald = NULL;
     1309  ZLocations_t location;
     1310  int numlocs, ret, notify;
     1311
     1312  /* Find a ZALD to match this notice. */
     1313  zaldlist = owl_global_get_zaldlist(&g);
     1314  zaldptr = g_list_first(*zaldlist);
     1315  while (zaldptr) {
     1316    if (ZCompareALDPred(n, zaldptr->data)) {
     1317      zald = zaldptr->data;
     1318      *zaldlist = g_list_remove(*zaldlist, zaldptr->data);
     1319      break;
     1320    }
     1321    zaldptr = g_list_next(zaldptr);
     1322  }
     1323  if (zald) {
     1324    /* Deal with notice. */
     1325    notify = owl_global_get_pseudologin_notify(&g);
     1326    zbl = owl_global_get_zephyr_buddylist(&g);
     1327    ret = ZParseLocations(n, zald, &numlocs, NULL);
     1328    if (ret == ZERR_NONE) {
     1329      if (numlocs > 0 && !owl_zbuddylist_contains_user(zbl, zald->user)) {
     1330        if (notify) {
     1331          numlocs = 1;
     1332          ret = ZGetLocations(&location, &numlocs);
     1333          if (ret == ZERR_NONE) {
     1334            /* Send a PSEUDO LOGIN! */
     1335            m = owl_malloc(sizeof(owl_message));
     1336            owl_message_create_pseudo_zlogin(m, 0, zald->user,
     1337                                             location.host,
     1338                                             location.time,
     1339                                             location.tty);
     1340            owl_global_messagequeue_addmsg(&g, m);
     1341          }
     1342          owl_zbuddylist_adduser(zbl, zald->user);
     1343          owl_function_debugmsg("owl_function_zephyr_buddy_check: login for %s ", zald->user);
     1344        }
     1345      } else if (numlocs == 0 && owl_zbuddylist_contains_user(zbl, zald->user)) {
     1346        /* Send a PSEUDO LOGOUT! */
     1347        if (notify) {
     1348          m = owl_malloc(sizeof(owl_message));
     1349          owl_message_create_pseudo_zlogin(m, 1, zald->user, "", "", "");
     1350          owl_global_messagequeue_addmsg(&g, m);
     1351        }
     1352        owl_zbuddylist_deluser(zbl, zald->user);
     1353        owl_function_debugmsg("owl_function_zephyr_buddy_check: logout for %s ", zald->user);
     1354      }
     1355    }
     1356    ZFreeALD(zald);
     1357    owl_free(zald);
     1358  }
     1359}
     1360#else
     1361void owl_zephyr_process_pseudologin(void *n)
     1362{
     1363}
     1364#endif
     1365
    13011366/*
    13021367 * Process zephyrgrams from libzephyr's queue. To prevent starvation,
     
    13331398      }
    13341399
     1400      /* if it is a LOCATE message, it's for pseudologins. */
     1401      if (strcmp(notice.z_opcode, LOCATE_LOCATE) == 0) {
     1402        owl_zephyr_process_pseudologin(&notice);
     1403        ZFreeNotice(&notice);
     1404        continue;
     1405      }
     1406
    13351407      /* create the new message */
    13361408      m=owl_malloc(sizeof(owl_message));
Note: See TracChangeset for help on using the changeset viewer.