/[winpt]/trunk/Gnupg/sha1.c
ViewVC logotype

Diff of /trunk/Gnupg/sha1.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 45 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 46 by werner, Fri Oct 28 12:57:05 2005 UTC
# Line 1  Line 1 
1  /* sha1.c - SHA1 hash function  /* sha1.c - SHA1 hash function
2   *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.   *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3   *   *
4   * Please see below for more legal information!   * Please see below for more legal information!
5   *   *
6   * This file is part of GnuPG.   * This file is part of GnuPG.
7   *   *
8   * GnuPG is free software; you can redistribute it and/or modify   * GnuPG is free software; you can redistribute it and/or modify
9   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.   * (at your option) any later version.
12   *   *
13   * GnuPG is distributed in the hope that it will be useful,   * GnuPG is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.   * GNU General Public License for more details.
17   *   *
18   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
19   * along with this program; if not, write to the Free Software   * along with this program; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21   */   */
22    
23    
24  /*  Test vectors:  /*  Test vectors:
25   *   *
26   *  "abc"   *  "abc"
27   *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D   *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D
28   *   *
29   *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"   *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
30   *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1   *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1
31   */   */
32    
33    
34  #include <stdio.h>  #ifdef HAVE_CONFIG_H
35  #include <stdlib.h>  #include <config.h>
36  #include <string.h>  #endif
37  #include <assert.h>  
38    #include <stdio.h>
39  #include "md.h"  #include <stdio.h>
40    #include <stdlib.h>
41  static void  #include <string.h>
42  burn_stack (int bytes)  #include <assert.h>
43  {  
44      char buf[128];  #include "md.h"
45        
46      memset(buf, 0, sizeof buf);  static void
47      bytes -= sizeof buf;  burn_stack (int bytes)
48      if (bytes > 0)  {
49          burn_stack (bytes);      char buf[128];
50  }      
51        memset(buf, 0, sizeof buf);
52        bytes -= sizeof buf;
53  void      if (bytes > 0)
54  sha1_init( SHA1_CONTEXT *hd )          burn_stack (bytes);
55  {  }
56      hd->h0 = 0x67452301;  
57      hd->h1 = 0xefcdab89;  
58      hd->h2 = 0x98badcfe;  void
59      hd->h3 = 0x10325476;  sha1_init( SHA1_CONTEXT *hd )
60      hd->h4 = 0xc3d2e1f0;  {
61      hd->nblocks = 0;      hd->h0 = 0x67452301;
62      hd->count = 0;      hd->h1 = 0xefcdab89;
63  }      hd->h2 = 0x98badcfe;
64        hd->h3 = 0x10325476;
65        hd->h4 = 0xc3d2e1f0;
66  /****************      hd->nblocks = 0;
67   * Transform the message X which consists of 16 32-bit-words      hd->count = 0;
68   */  }
69  static void  
70  transform( SHA1_CONTEXT *hd, unsigned char *data )  
71  {  /****************
72      unsigned long a,b,c,d,e,tm;   * Transform the message X which consists of 16 32-bit-words
73      unsigned long x[16];   */
74    static void
75      /* get values from the chaining vars */  transform( SHA1_CONTEXT *hd, unsigned char *data )
76      a = hd->h0;  {
77      b = hd->h1;      unsigned long a,b,c,d,e,tm;
78      c = hd->h2;      unsigned long x[16];
79      d = hd->h3;  
80      e = hd->h4;      /* get values from the chaining vars */
81        a = hd->h0;
82    #ifdef BIG_ENDIAN_HOST      b = hd->h1;
83      memcpy( x, data, 64 );      c = hd->h2;
84    #else      d = hd->h3;
85      { int i;      e = hd->h4;
86        unsigned char *p2;  
87        for(i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) {    #ifdef BIG_ENDIAN_HOST
88          p2[3] = *data++;      memcpy( x, data, 64 );
89          p2[2] = *data++;    #else
90          p2[1] = *data++;      { int i;
91          p2[0] = *data++;        unsigned char *p2;
92        }        for(i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) {
93      }          p2[3] = *data++;
94    #endif          p2[2] = *data++;
95            p2[1] = *data++;
96            p2[0] = *data++;
97  #define K1  0x5A827999L        }
98  #define K2  0x6ED9EBA1L      }
99  #define K3  0x8F1BBCDCL    #endif
100  #define K4  0xCA62C1D6L  
101  #define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )  
102  #define F2(x,y,z)   ( x ^ y ^ z )  #define K1  0x5A827999L
103  #define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )  #define K2  0x6ED9EBA1L
104  #define F4(x,y,z)   ( x ^ y ^ z )  #define K3  0x8F1BBCDCL
105    #define K4  0xCA62C1D6L
106    #define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )
107  #define M(i) ( tm =   x[i&0x0f] ^ x[(i-14)&0x0f] \  #define F2(x,y,z)   ( x ^ y ^ z )
108                      ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \  #define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )
109                 , (x[i&0x0f] = rol(tm,1)) )  #define F4(x,y,z)   ( x ^ y ^ z )
110    
111  #define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \  
112                                        + f( b, c, d )  \  #define M(i) ( tm =   x[i&0x0f] ^ x[(i-14)&0x0f] \
113                                        + k             \                      ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
114                                        + m;            \                 , (x[i&0x0f] = rol(tm,1)) )
115                                   b = rol( b, 30 );    \  
116                                 } while(0)  #define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \
117      R( a, b, c, d, e, F1, K1, x[ 0] );                                        + f( b, c, d )  \
118      R( e, a, b, c, d, F1, K1, x[ 1] );                                        + k             \
119      R( d, e, a, b, c, F1, K1, x[ 2] );                                        + m;            \
120      R( c, d, e, a, b, F1, K1, x[ 3] );                                   b = rol( b, 30 );    \
121      R( b, c, d, e, a, F1, K1, x[ 4] );                                 } while(0)
122      R( a, b, c, d, e, F1, K1, x[ 5] );      R( a, b, c, d, e, F1, K1, x[ 0] );
123      R( e, a, b, c, d, F1, K1, x[ 6] );      R( e, a, b, c, d, F1, K1, x[ 1] );
124      R( d, e, a, b, c, F1, K1, x[ 7] );      R( d, e, a, b, c, F1, K1, x[ 2] );
125      R( c, d, e, a, b, F1, K1, x[ 8] );      R( c, d, e, a, b, F1, K1, x[ 3] );
126      R( b, c, d, e, a, F1, K1, x[ 9] );      R( b, c, d, e, a, F1, K1, x[ 4] );
127      R( a, b, c, d, e, F1, K1, x[10] );      R( a, b, c, d, e, F1, K1, x[ 5] );
128      R( e, a, b, c, d, F1, K1, x[11] );      R( e, a, b, c, d, F1, K1, x[ 6] );
129      R( d, e, a, b, c, F1, K1, x[12] );      R( d, e, a, b, c, F1, K1, x[ 7] );
130      R( c, d, e, a, b, F1, K1, x[13] );      R( c, d, e, a, b, F1, K1, x[ 8] );
131      R( b, c, d, e, a, F1, K1, x[14] );      R( b, c, d, e, a, F1, K1, x[ 9] );
132      R( a, b, c, d, e, F1, K1, x[15] );      R( a, b, c, d, e, F1, K1, x[10] );
133      R( e, a, b, c, d, F1, K1, M(16) );      R( e, a, b, c, d, F1, K1, x[11] );
134      R( d, e, a, b, c, F1, K1, M(17) );      R( d, e, a, b, c, F1, K1, x[12] );
135      R( c, d, e, a, b, F1, K1, M(18) );      R( c, d, e, a, b, F1, K1, x[13] );
136      R( b, c, d, e, a, F1, K1, M(19) );      R( b, c, d, e, a, F1, K1, x[14] );
137      R( a, b, c, d, e, F2, K2, M(20) );      R( a, b, c, d, e, F1, K1, x[15] );
138      R( e, a, b, c, d, F2, K2, M(21) );      R( e, a, b, c, d, F1, K1, M(16) );
139      R( d, e, a, b, c, F2, K2, M(22) );      R( d, e, a, b, c, F1, K1, M(17) );
140      R( c, d, e, a, b, F2, K2, M(23) );      R( c, d, e, a, b, F1, K1, M(18) );
141      R( b, c, d, e, a, F2, K2, M(24) );      R( b, c, d, e, a, F1, K1, M(19) );
142      R( a, b, c, d, e, F2, K2, M(25) );      R( a, b, c, d, e, F2, K2, M(20) );
143      R( e, a, b, c, d, F2, K2, M(26) );      R( e, a, b, c, d, F2, K2, M(21) );
144      R( d, e, a, b, c, F2, K2, M(27) );      R( d, e, a, b, c, F2, K2, M(22) );
145      R( c, d, e, a, b, F2, K2, M(28) );      R( c, d, e, a, b, F2, K2, M(23) );
146      R( b, c, d, e, a, F2, K2, M(29) );      R( b, c, d, e, a, F2, K2, M(24) );
147      R( a, b, c, d, e, F2, K2, M(30) );      R( a, b, c, d, e, F2, K2, M(25) );
148      R( e, a, b, c, d, F2, K2, M(31) );      R( e, a, b, c, d, F2, K2, M(26) );
149      R( d, e, a, b, c, F2, K2, M(32) );      R( d, e, a, b, c, F2, K2, M(27) );
150      R( c, d, e, a, b, F2, K2, M(33) );      R( c, d, e, a, b, F2, K2, M(28) );
151      R( b, c, d, e, a, F2, K2, M(34) );      R( b, c, d, e, a, F2, K2, M(29) );
152      R( a, b, c, d, e, F2, K2, M(35) );      R( a, b, c, d, e, F2, K2, M(30) );
153      R( e, a, b, c, d, F2, K2, M(36) );      R( e, a, b, c, d, F2, K2, M(31) );
154      R( d, e, a, b, c, F2, K2, M(37) );      R( d, e, a, b, c, F2, K2, M(32) );
155      R( c, d, e, a, b, F2, K2, M(38) );      R( c, d, e, a, b, F2, K2, M(33) );
156      R( b, c, d, e, a, F2, K2, M(39) );      R( b, c, d, e, a, F2, K2, M(34) );
157      R( a, b, c, d, e, F3, K3, M(40) );      R( a, b, c, d, e, F2, K2, M(35) );
158      R( e, a, b, c, d, F3, K3, M(41) );      R( e, a, b, c, d, F2, K2, M(36) );
159      R( d, e, a, b, c, F3, K3, M(42) );      R( d, e, a, b, c, F2, K2, M(37) );
160      R( c, d, e, a, b, F3, K3, M(43) );      R( c, d, e, a, b, F2, K2, M(38) );
161      R( b, c, d, e, a, F3, K3, M(44) );      R( b, c, d, e, a, F2, K2, M(39) );
162      R( a, b, c, d, e, F3, K3, M(45) );      R( a, b, c, d, e, F3, K3, M(40) );
163      R( e, a, b, c, d, F3, K3, M(46) );      R( e, a, b, c, d, F3, K3, M(41) );
164      R( d, e, a, b, c, F3, K3, M(47) );      R( d, e, a, b, c, F3, K3, M(42) );
165      R( c, d, e, a, b, F3, K3, M(48) );      R( c, d, e, a, b, F3, K3, M(43) );
166      R( b, c, d, e, a, F3, K3, M(49) );      R( b, c, d, e, a, F3, K3, M(44) );
167      R( a, b, c, d, e, F3, K3, M(50) );      R( a, b, c, d, e, F3, K3, M(45) );
168      R( e, a, b, c, d, F3, K3, M(51) );      R( e, a, b, c, d, F3, K3, M(46) );
169      R( d, e, a, b, c, F3, K3, M(52) );      R( d, e, a, b, c, F3, K3, M(47) );
170      R( c, d, e, a, b, F3, K3, M(53) );      R( c, d, e, a, b, F3, K3, M(48) );
171      R( b, c, d, e, a, F3, K3, M(54) );      R( b, c, d, e, a, F3, K3, M(49) );
172      R( a, b, c, d, e, F3, K3, M(55) );      R( a, b, c, d, e, F3, K3, M(50) );
173      R( e, a, b, c, d, F3, K3, M(56) );      R( e, a, b, c, d, F3, K3, M(51) );
174      R( d, e, a, b, c, F3, K3, M(57) );      R( d, e, a, b, c, F3, K3, M(52) );
175      R( c, d, e, a, b, F3, K3, M(58) );      R( c, d, e, a, b, F3, K3, M(53) );
176      R( b, c, d, e, a, F3, K3, M(59) );      R( b, c, d, e, a, F3, K3, M(54) );
177      R( a, b, c, d, e, F4, K4, M(60) );      R( a, b, c, d, e, F3, K3, M(55) );
178      R( e, a, b, c, d, F4, K4, M(61) );      R( e, a, b, c, d, F3, K3, M(56) );
179      R( d, e, a, b, c, F4, K4, M(62) );      R( d, e, a, b, c, F3, K3, M(57) );
180      R( c, d, e, a, b, F4, K4, M(63) );      R( c, d, e, a, b, F3, K3, M(58) );
181      R( b, c, d, e, a, F4, K4, M(64) );      R( b, c, d, e, a, F3, K3, M(59) );
182      R( a, b, c, d, e, F4, K4, M(65) );      R( a, b, c, d, e, F4, K4, M(60) );
183      R( e, a, b, c, d, F4, K4, M(66) );      R( e, a, b, c, d, F4, K4, M(61) );
184      R( d, e, a, b, c, F4, K4, M(67) );      R( d, e, a, b, c, F4, K4, M(62) );
185      R( c, d, e, a, b, F4, K4, M(68) );      R( c, d, e, a, b, F4, K4, M(63) );
186      R( b, c, d, e, a, F4, K4, M(69) );      R( b, c, d, e, a, F4, K4, M(64) );
187      R( a, b, c, d, e, F4, K4, M(70) );      R( a, b, c, d, e, F4, K4, M(65) );
188      R( e, a, b, c, d, F4, K4, M(71) );      R( e, a, b, c, d, F4, K4, M(66) );
189      R( d, e, a, b, c, F4, K4, M(72) );      R( d, e, a, b, c, F4, K4, M(67) );
190      R( c, d, e, a, b, F4, K4, M(73) );      R( c, d, e, a, b, F4, K4, M(68) );
191      R( b, c, d, e, a, F4, K4, M(74) );      R( b, c, d, e, a, F4, K4, M(69) );
192      R( a, b, c, d, e, F4, K4, M(75) );      R( a, b, c, d, e, F4, K4, M(70) );
193      R( e, a, b, c, d, F4, K4, M(76) );      R( e, a, b, c, d, F4, K4, M(71) );
194      R( d, e, a, b, c, F4, K4, M(77) );      R( d, e, a, b, c, F4, K4, M(72) );
195      R( c, d, e, a, b, F4, K4, M(78) );      R( c, d, e, a, b, F4, K4, M(73) );
196      R( b, c, d, e, a, F4, K4, M(79) );      R( b, c, d, e, a, F4, K4, M(74) );
197        R( a, b, c, d, e, F4, K4, M(75) );
198      /* update chainig vars */      R( e, a, b, c, d, F4, K4, M(76) );
199      hd->h0 += a;      R( d, e, a, b, c, F4, K4, M(77) );
200      hd->h1 += b;      R( c, d, e, a, b, F4, K4, M(78) );
201      hd->h2 += c;      R( b, c, d, e, a, F4, K4, M(79) );
202      hd->h3 += d;  
203      hd->h4 += e;      /* update chainig vars */
204  }      hd->h0 += a;
205        hd->h1 += b;
206        hd->h2 += c;
207  /* Update the message digest with the contents      hd->h3 += d;
208   * of INBUF with length INLEN.      hd->h4 += e;
209   */  }
210   void  
211  sha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen)  
212  {  /* Update the message digest with the contents
213      if( hd->count == 64 ) { /* flush the buffer */   * of INBUF with length INLEN.
214          transform( hd, hd->buf );   */
215          burn_stack (88+4*sizeof(void*));   void
216          hd->count = 0;  sha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen)
217          hd->nblocks++;  {
218      }      if( hd->count == 64 ) { /* flush the buffer */
219      if( !inbuf )          transform( hd, hd->buf );
220          return;          burn_stack (88+4*sizeof(void*));
221      if( hd->count ) {          hd->count = 0;
222          for( ; inlen && hd->count < 64; inlen-- )          hd->nblocks++;
223              hd->buf[hd->count++] = *inbuf++;      }
224          sha1_write( hd, NULL, 0 );      if( !inbuf )
225          if( !inlen )          return;
226              return;      if( hd->count ) {
227      }          for( ; inlen && hd->count < 64; inlen-- )
228                hd->buf[hd->count++] = *inbuf++;
229      while( inlen >= 64 ) {          sha1_write( hd, NULL, 0 );
230          transform( hd, inbuf );          if( !inlen )
231          hd->count = 0;              return;
232          hd->nblocks++;      }
233          inlen -= 64;  
234          inbuf += 64;      while( inlen >= 64 ) {
235      }          transform( hd, inbuf );
236      burn_stack (88+4*sizeof(void*));          hd->count = 0;
237      for( ; inlen && hd->count < 64; inlen-- )          hd->nblocks++;
238          hd->buf[hd->count++] = *inbuf++;          inlen -= 64;
239  }          inbuf += 64;
240        }
241        burn_stack (88+4*sizeof(void*));
242  /* The routine final terminates the computation and      for( ; inlen && hd->count < 64; inlen-- )
243   * returns the digest.          hd->buf[hd->count++] = *inbuf++;
244   * The handle is prepared for a new cycle, but adding bytes to the  }
245   * handle will the destroy the returned buffer.  
246   * Returns: 20 bytes representing the digest.  
247   */  /* The routine final terminates the computation and
248     * returns the digest.
249   void   * The handle is prepared for a new cycle, but adding bytes to the
250  sha1_final(SHA1_CONTEXT *hd)   * handle will the destroy the returned buffer.
251  {   * Returns: 20 bytes representing the digest.
252      unsigned long t, msb, lsb;   */
253      unsigned char *p;  
254     void
255      sha1_write(hd, NULL, 0); /* flush */;  sha1_final(SHA1_CONTEXT *hd)
256    {
257      t = hd->nblocks;      unsigned long t, msb, lsb;
258      /* multiply by 64 to make a byte count */      unsigned char *p;
259      lsb = t << 6;  
260      msb = t >> 26;      sha1_write(hd, NULL, 0); /* flush */;
261      /* add the count */  
262      t = lsb;      t = hd->nblocks;
263      if( (lsb += hd->count) < t )      /* multiply by 64 to make a byte count */
264          msb++;      lsb = t << 6;
265      /* multiply by 8 to make a bit count */      msb = t >> 26;
266      t = lsb;      /* add the count */
267      lsb <<= 3;      t = lsb;
268      msb <<= 3;      if( (lsb += hd->count) < t )
269      msb |= t >> 29;          msb++;
270        /* multiply by 8 to make a bit count */
271      if( hd->count < 56 ) { /* enough room */      t = lsb;
272          hd->buf[hd->count++] = 0x80; /* pad */      lsb <<= 3;
273          while( hd->count < 56 )      msb <<= 3;
274              hd->buf[hd->count++] = 0;  /* pad */      msb |= t >> 29;
275      }  
276      else { /* need one extra block */      if( hd->count < 56 ) { /* enough room */
277          hd->buf[hd->count++] = 0x80; /* pad character */          hd->buf[hd->count++] = 0x80; /* pad */
278          while( hd->count < 64 )          while( hd->count < 56 )
279              hd->buf[hd->count++] = 0;              hd->buf[hd->count++] = 0;  /* pad */
280          sha1_write(hd, NULL, 0);  /* flush */;      }
281          memset(hd->buf, 0, 56 ); /* fill next block with zeroes */      else { /* need one extra block */
282      }          hd->buf[hd->count++] = 0x80; /* pad character */
283      /* append the 64 bit count */          while( hd->count < 64 )
284      hd->buf[56] = msb >> 24;              hd->buf[hd->count++] = 0;
285      hd->buf[57] = msb >> 16;          sha1_write(hd, NULL, 0);  /* flush */;
286      hd->buf[58] = msb >>  8;          memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
287      hd->buf[59] = msb      ;      }
288      hd->buf[60] = lsb >> 24;      /* append the 64 bit count */
289      hd->buf[61] = lsb >> 16;      hd->buf[56] = msb >> 24;
290      hd->buf[62] = lsb >>  8;      hd->buf[57] = msb >> 16;
291      hd->buf[63] = lsb      ;      hd->buf[58] = msb >>  8;
292      transform( hd, hd->buf );      hd->buf[59] = msb      ;
293      burn_stack (88+4*sizeof(void*));      hd->buf[60] = lsb >> 24;
294        hd->buf[61] = lsb >> 16;
295      p = hd->buf;      hd->buf[62] = lsb >>  8;
296    #ifdef BIG_ENDIAN_HOST      hd->buf[63] = lsb      ;
297      #define X(a) do { *(unsigned long*)p = hd->h##a ; p += 4; } while(0)      transform( hd, hd->buf );
298    #else /* little endian */      burn_stack (88+4*sizeof(void*));
299      #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;      \  
300                        *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)      p = hd->buf;
301    #endif    #ifdef BIG_ENDIAN_HOST
302      X(0);      #define X(a) do { *(unsigned long*)p = hd->h##a ; p += 4; } while(0)
303      X(1);    #else /* little endian */
304      X(2);      #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;      \
305      X(3);                        *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
306      X(4);    #endif
307    #undef X      X(0);
308        X(1);
309  }      X(2);
310        X(3);
311  unsigned char *      X(4);
312  sha1_read( SHA1_CONTEXT *hd )    #undef X
313  {  
314      return hd->buf;  }
315  }  
316    unsigned char *
317    sha1_read( SHA1_CONTEXT *hd )
318    {
319        return hd->buf;
320    }
321    

Legend:
Removed from v.45  
changed lines
  Added in v.46

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26