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 3 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, see <http://www.gnu.org/licenses/>. 19*/ 20 21#include "includes.h" 22 23static struct { 24 char from; 25 const char *to; 26 int len; 27} weird_table[] = { 28 {'q', "^q^", 3}, 29 {'Q', "^Q^", 3}, 30 {0, NULL} 31}; 32 33static size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft, 34 char **outbuf, size_t *outbytesleft) 35{ 36 while (*inbytesleft >= 1 && *outbytesleft >= 2) { 37 int i; 38 int done = 0; 39 for (i=0;weird_table[i].from;i++) { 40 if (strncmp((*inbuf), 41 weird_table[i].to, 42 weird_table[i].len) == 0) { 43 if (*inbytesleft < weird_table[i].len) { 44 DEBUG(0,("ERROR: truncated weird string\n")); 45 /* smb_panic("weird_pull"); */ 46 47 } else { 48 (*outbuf)[0] = weird_table[i].from; 49 (*outbuf)[1] = 0; 50 (*inbytesleft) -= weird_table[i].len; 51 (*outbytesleft) -= 2; 52 (*inbuf) += weird_table[i].len; 53 (*outbuf) += 2; 54 done = 1; 55 break; 56 } 57 } 58 } 59 if (done) continue; 60 (*outbuf)[0] = (*inbuf)[0]; 61 (*outbuf)[1] = 0; 62 (*inbytesleft) -= 1; 63 (*outbytesleft) -= 2; 64 (*inbuf) += 1; 65 (*outbuf) += 2; 66 } 67 68 if (*inbytesleft > 0) { 69 errno = E2BIG; 70 return -1; 71 } 72 73 return 0; 74} 75 76static size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft, 77 char **outbuf, size_t *outbytesleft) 78{ 79 int ir_count=0; 80 81 while (*inbytesleft >= 2 && *outbytesleft >= 1) { 82 int i; 83 int done=0; 84 for (i=0;weird_table[i].from;i++) { 85 if ((*inbuf)[0] == weird_table[i].from && 86 (*inbuf)[1] == 0) { 87 if (*outbytesleft < weird_table[i].len) { 88 DEBUG(0,("No room for weird character\n")); 89 /* smb_panic("weird_push"); */ 90 } else { 91 memcpy(*outbuf, weird_table[i].to, 92 weird_table[i].len); 93 (*inbytesleft) -= 2; 94 (*outbytesleft) -= weird_table[i].len; 95 (*inbuf) += 2; 96 (*outbuf) += weird_table[i].len; 97 done = 1; 98 break; 99 } 100 } 101 } 102 if (done) continue; 103 104 (*outbuf)[0] = (*inbuf)[0]; 105 if ((*inbuf)[1]) ir_count++; 106 (*inbytesleft) -= 2; 107 (*outbytesleft) -= 1; 108 (*inbuf) += 2; 109 (*outbuf) += 1; 110 } 111 112 if (*inbytesleft == 1) { 113 errno = EINVAL; 114 return -1; 115 } 116 117 if (*inbytesleft > 1) { 118 errno = E2BIG; 119 return -1; 120 } 121 122 return ir_count; 123} 124 125struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push}; 126 127NTSTATUS charset_weird_init(void); 128NTSTATUS charset_weird_init(void) 129{ 130 return smb_register_charset(&weird_functions); 131} 132