1/* 2 Unix SMB/CIFS implementation. 3 Samba module with developer tools 4 Copyright (C) Andrew Tridgell 2001 5 Copyright (C) Jelmer Vernooij 2002 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*/ 21 22#include "includes.h" 23 24static struct { 25 char from; 26 char *to; 27 int len; 28} weird_table[] = { 29 {'q', "^q^", 3}, 30 {'Q', "^Q^", 3}, 31 {0, NULL} 32}; 33 34static size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft, 35 char **outbuf, size_t *outbytesleft) 36{ 37 while (*inbytesleft >= 1 && *outbytesleft >= 2) { 38 int i; 39 int done = 0; 40 for (i=0;weird_table[i].from;i++) { 41 if (strncmp((*inbuf), 42 weird_table[i].to, 43 weird_table[i].len) == 0) { 44 if (*inbytesleft < weird_table[i].len) { 45 DEBUG(0,("ERROR: truncated weird string\n")); 46 /* smb_panic("weird_pull"); */ 47 48 } else { 49 (*outbuf)[0] = weird_table[i].from; 50 (*outbuf)[1] = 0; 51 (*inbytesleft) -= weird_table[i].len; 52 (*outbytesleft) -= 2; 53 (*inbuf) += weird_table[i].len; 54 (*outbuf) += 2; 55 done = 1; 56 break; 57 } 58 } 59 } 60 if (done) continue; 61 (*outbuf)[0] = (*inbuf)[0]; 62 (*outbuf)[1] = 0; 63 (*inbytesleft) -= 1; 64 (*outbytesleft) -= 2; 65 (*inbuf) += 1; 66 (*outbuf) += 2; 67 } 68 69 if (*inbytesleft > 0) { 70 errno = E2BIG; 71 return -1; 72 } 73 74 return 0; 75} 76 77static size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft, 78 char **outbuf, size_t *outbytesleft) 79{ 80 int ir_count=0; 81 82 while (*inbytesleft >= 2 && *outbytesleft >= 1) { 83 int i; 84 int done=0; 85 for (i=0;weird_table[i].from;i++) { 86 if ((*inbuf)[0] == weird_table[i].from && 87 (*inbuf)[1] == 0) { 88 if (*outbytesleft < weird_table[i].len) { 89 DEBUG(0,("No room for weird character\n")); 90 /* smb_panic("weird_push"); */ 91 } else { 92 memcpy(*outbuf, weird_table[i].to, 93 weird_table[i].len); 94 (*inbytesleft) -= 2; 95 (*outbytesleft) -= weird_table[i].len; 96 (*inbuf) += 2; 97 (*outbuf) += weird_table[i].len; 98 done = 1; 99 break; 100 } 101 } 102 } 103 if (done) continue; 104 105 (*outbuf)[0] = (*inbuf)[0]; 106 if ((*inbuf)[1]) ir_count++; 107 (*inbytesleft) -= 2; 108 (*outbytesleft) -= 1; 109 (*inbuf) += 2; 110 (*outbuf) += 1; 111 } 112 113 if (*inbytesleft == 1) { 114 errno = EINVAL; 115 return -1; 116 } 117 118 if (*inbytesleft > 1) { 119 errno = E2BIG; 120 return -1; 121 } 122 123 return ir_count; 124} 125 126struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push}; 127 128NTSTATUS charset_weird_init(void) 129{ 130 return smb_register_charset(&weird_functions); 131} 132