2 * \file ferret/examples/merge_mon/uu.c
3 * \brief UUencoding functions, mostly from jdb
6 * \author Martin Pohlack <mp26@os.inf.tu-dresden.de>
9 * (c) 2005-2009 Technische Universität Dresden
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
15 /* ENC is the basic 1 character encoding function to make a char printing */
16 #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
21 #include <sys/types.h>
25 #include <l4/plr/uu.h>
27 #define MIN(a, b) ((a)<(b)?(a):(b))
33 /* Init. zlib data structures, available input data and start address
35 static void init_z(size_t len, const void *start)
41 ret = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 15 + 16, 9,
46 strm.next_in = (void *)start; // oh why ...
49 static int get_next_chunk(void *dest, ssize_t n, int flush)
55 ret = deflate(&strm, flush);
56 assert(ret != Z_STREAM_ERROR);
57 return n - strm.avail_out;
60 static void update_in_data(const unsigned char * buf, size_t * len)
62 if (strm.avail_in == 0 && *len != 0)
65 strm.next_in = (void *)buf; // oh why ...
70 void uu_dumpz(const char * filename, const unsigned char * s_buf, size_t len)
74 const unsigned char *p_buf;
76 static unsigned char in[LINE_IN + 3]; // some spare zeros for uuencode
77 static unsigned char out[70];
78 int flush = Z_NO_FLUSH;
83 printf("begin 644 %s.gz\n", filename);
87 // get next line of data
88 n = get_next_chunk(in, LINE_IN, flush);
89 if (n < LINE_IN && flush == Z_NO_FLUSH)
91 flush = Z_FINISH; // time to clean up now
92 n += get_next_chunk(in + n, LINE_IN - n, flush);
94 else if (n == 0 && flush == Z_FINISH)
95 break; // no more data available, leave loop
96 memset(in + n, 0, sizeof(in) - n);
100 // line length prefix
103 for (p_buf = in; n > 0; n -= 3, p_buf += 3)
108 ch = ((*p_buf << 4) & 060) | ((p_buf[1] >> 4) & 017);
111 ch = ((p_buf[1] << 2) & 074) | ((p_buf[2] >> 6) & 03);
118 // skip this newline for log output
119 //out[out_i++] = '\n';
121 puts((char const*)out); // write it
124 ret = deflateEnd(&strm);
131 /* Also works in ring buffers with wrap-around
133 void uu_dumpz_ringbuffer(const char * filename,
134 const void * _buffer, size_t buffer_len,
135 unsigned start_offset, size_t transfer_size)
138 unsigned char * buffer = (unsigned char *)_buffer;
139 static unsigned char in[LINE_IN + 3]; // some spare zeros for uuencode
140 static unsigned char out[70];
141 int flush = Z_NO_FLUSH;
142 size_t first_len = MIN(transfer_size, buffer_len - start_offset);
144 assert((unsigned)start_offset < buffer_len);
145 assert(transfer_size <= buffer_len);
147 // init. zlib stream for first chunk
148 init_z(first_len, buffer + start_offset);
149 transfer_size -= first_len;
152 printf("begin 644 %s.gz\n", filename);
158 const unsigned char * p_buf;
160 // get next line of data
161 n = get_next_chunk(in, LINE_IN, flush);
162 update_in_data(buffer, &transfer_size);
163 if (n < LINE_IN && flush == Z_NO_FLUSH)
165 flush = Z_FINISH; // time to clean up now
166 n += get_next_chunk(in + n, LINE_IN - n, flush);
167 update_in_data(buffer, &transfer_size);
169 else if (n == 0 && flush == Z_FINISH)
170 break; // no more data available, leave loop
171 memset(in + n, 0, sizeof(in) - n);
173 // fill output buffer
175 // line length prefix
178 for (p_buf = in; n > 0; n -= 3, p_buf += 3)
183 ch = ((*p_buf << 4) & 060) | ((p_buf[1] >> 4) & 017);
186 ch = ((p_buf[1] << 2) & 074) | ((p_buf[2] >> 6) & 03);
193 // skip this newline for log output
194 //out[out_i++] = '\n';
196 puts((char const *)out); // write it
199 ret = deflateEnd(&strm);
207 void uu_dump(const char * filename, const buf_t * buf)
211 const unsigned char *p_buf;
212 unsigned char *s_buf = buf->start;
214 static unsigned char in[48];
215 static unsigned char out[70];
216 size_t len = buf->write_pos - buf->start;
219 //printf("%hhx %hhx %hhx %hhx\n", ENC(8), ENC(64), ENC(4), ENC(2));
222 printf("begin 644 %s\n", filename);
226 // get next line of data
235 memcpy(in, s_buf, n);
236 memset(in + n, 0, sizeof(in) - n);
240 // fill output buffer
242 // line length prefix
245 for (p_buf = in; n > 0; n -= 3, p_buf += 3)
250 ch = ((*p_buf << 4) & 060) | ((p_buf[1] >> 4) & 017);
253 ch = ((p_buf[1] << 2) & 074) | ((p_buf[2] >> 6) & 03);
260 // skip this newline for log output
261 //out[out_i++] = '\n';