00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #ifdef _MSC_VER
00023 #include "config.h.win32"
00024 #else
00025 #include "config.h"
00026 #endif
00027 #endif
00028
00029 #ifdef SYSTEM_WINDLL
00030 #include
00031 #endif
00032 #ifdef SYSTEM_OS2
00033 #include
00034 #endif
00035
00036 #include
00037 #include
00038
00039 #ifdef STDC_HEADERS
00040 #include
00041 #include
00042 #endif
00043 #ifdef HAVE_MALLOC_H
00044 #include
00045 #endif
00046 #ifdef HAVE_UNISTD_H
00047 #include
00048 #endif
00049 #ifdef HAVE_MEMORY_H
00050 #include
00051 #endif
00052 #ifdef HAVE_ERRNO_H
00053 #include
00054 #endif
00055
00056 #include <uudeview.h>
00057 #include <uuint.h>
00058 #include <fptools.h>
00059 #include <uustring.h>
00060
00061 char * uuutil_id = "$Id: uuutil.c 2 2006-10-02 20:45:58Z csk $";
00062
00063
00064
00065
00066
00067
00068 static char *knownexts[] = {
00069 "mpg", "@mpeg", "avi", "mov",
00070 "gif", "jpg", "@jpeg", "tif",
00071 "voc", "wav", "@wave", "au",
00072 "zip", "arj", "tar",
00073 NULL
00074 };
00075
00076
00077
00078
00079
00080 static int UUSMPKnownExt _ANSI_ARGS_((char *filename));
00081 static uulist * UU_smparts_r _ANSI_ARGS_((uulist *, int));
00082
00083
00084
00085
00086
00087 char *uuutil_bhwtmp;
00088
00089
00090
00091
00092
00093 void
00094 UUkillfread (fileread *data)
00095 {
00096 if (data != NULL) {
00097 _FP_free (data->subject);
00098 _FP_free (data->filename);
00099 _FP_free (data->origin);
00100 _FP_free (data->mimeid);
00101 _FP_free (data->mimetype);
00102 _FP_free (data->sfname);
00103 _FP_free (data);
00104 }
00105 }
00106
00107 void
00108 UUkillfile (uufile *data)
00109 {
00110 uufile *next;
00111
00112 while (data) {
00113 _FP_free (data->filename);
00114 _FP_free (data->subfname);
00115 _FP_free (data->mimeid);
00116 _FP_free (data->mimetype);
00117 UUkillfread (data->data);
00118
00119 next = data->NEXT;
00120 _FP_free (data);
00121 data = next;
00122 }
00123 }
00124
00125 void
00126 UUkilllist (uulist *data)
00127 {
00128 uulist *next;
00129
00130 while (data) {
00131 if (data->binfile != NULL)
00132 if (unlink (data->binfile))
00133 UUMessage (uuutil_id, __LINE__, UUMSG_WARNING,
00134 uustring (S_TMP_NOT_REMOVED),
00135 data->binfile, strerror (errno));
00136
00137 _FP_free (data->filename);
00138 _FP_free (data->subfname);
00139 _FP_free (data->mimeid);
00140 _FP_free (data->mimetype);
00141 _FP_free (data->binfile);
00142 UUkillfile (data->thisfile);
00143 _FP_free (data->haveparts);
00144 _FP_free (data->misparts);
00145
00146 next = data->NEXT;
00147 _FP_free (data);
00148 data = next;
00149 }
00150 }
00151
00152
00153
00154
00155
00156 void
00157 UUkillheaders (headers *data)
00158 {
00159 if (data != NULL) {
00160 _FP_free (data->from);
00161 _FP_free (data->subject);
00162 _FP_free (data->rcpt);
00163 _FP_free (data->date);
00164 _FP_free (data->mimevers);
00165 _FP_free (data->ctype);
00166 _FP_free (data->ctenc);
00167 _FP_free (data->fname);
00168 _FP_free (data->boundary);
00169 _FP_free (data->mimeid);
00170 memset (data, 0, sizeof (headers));
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179 static int
00180 UUSMPKnownExt (char *filename)
00181 {
00182 char **eiter = knownexts, *ptr=_FP_strrchr(filename, '.');
00183 int count=0, where=0;
00184
00185 if (ptr == NULL)
00186 return -1;
00187 ptr++;
00188
00189 while (*eiter) {
00190 if (_FP_stricmp (ptr, (**eiter=='@')?*eiter+1:*eiter) == 0)
00191 return where;
00192 else
00193 eiter++;
00194
00195 if (*eiter == NULL)
00196 break;
00197
00198 if (**eiter=='@')
00199 count++;
00200 else
00201 where = ++count;
00202 }
00203 return -1;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 int
00222 UUbhdecomp (char *in, char *out, char *last, int *rpc,
00223 size_t inc, size_t max, size_t *opc)
00224 {
00225 size_t count, used=0, dummy;
00226 char marker = '\220' ;
00227
00228 if (opc == NULL)
00229 opc = &dummy;
00230 else
00231 *opc = 0;
00232
00233 if (*rpc == -256) {
00234 if (inc == 0)
00235 return 0;
00236 *rpc = (int) (unsigned char) *in++; used++;
00237
00238 if (*rpc == 0) {
00239 *last = *out++ = marker;
00240 max--; *opc+=1;
00241 }
00242 else
00243 *rpc-=1;
00244 }
00245
00246 if (*rpc) {
00247 count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
00248
00249 memset (out, *last, count);
00250
00251 out += count;
00252 *opc += count;
00253 max -= count;
00254 *rpc -= count;
00255 }
00256
00257 while (used < inc && max) {
00258 if (*in == marker) {
00259 used++; in++;
00260 if (used == inc) {
00261 *rpc = -256;
00262 return used;
00263 }
00264 *rpc = (int) (unsigned char) *in++; used++;
00265
00266 if (*rpc == 0) {
00267 *last = *out++ = marker;
00268 max--; *opc+=1;
00269 continue;
00270 }
00271 else
00272 *rpc -= 1;
00273
00274 count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
00275 memset (out, *last, count);
00276
00277 out += count;
00278 *opc += count;
00279 max -= count;
00280 *rpc -= count;
00281 }
00282 else {
00283 *last = *out++ = *in++;
00284 used++; *opc+=1; max--;
00285 }
00286 }
00287
00288 return used;
00289 }
00290
00291
00292
00293
00294
00295 size_t
00296 UUbhwrite (char *ptr, size_t sel, size_t nel, FILE *file)
00297 {
00298 char *tmpstring=uuutil_bhwtmp;
00299 static int rpc = 0;
00300 static char lc;
00301 int count, tc=0;
00302 size_t opc;
00303
00304 if (ptr == NULL) {
00305 rpc = 0;
00306 return 0;
00307 }
00308
00309 while (nel || (rpc != 0 && rpc != -256)) {
00310 count = UUbhdecomp (ptr, tmpstring, &lc, &rpc,
00311 nel, 256, &opc);
00312 if (fwrite (tmpstring, 1, opc, file) != opc)
00313 return 0;
00314 if (ferror (file))
00315 return 0;
00316 nel -= count;
00317 ptr += count;
00318 tc += count;
00319 }
00320
00321 return tc;
00322 }
00323
00324 static uulist *
00325 UU_smparts_r (uulist *addit, int pass)
00326 {
00327 uulist *iter = UUGlobalFileList;
00328 uufile *fiter, *dest, *temp;
00329 int count, flag, a, b;
00330
00331 while (iter) {
00332 if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
00333 iter = iter->NEXT;
00334 continue;
00335 }
00336 if (iter == addit) {
00337 iter = iter->NEXT;
00338 continue;
00339 }
00340 if ((iter->begin && addit->begin) || (iter->end && addit->end) ||
00341 (iter->uudet != addit->uudet)) {
00342 iter = iter->NEXT;
00343 continue;
00344 }
00345 if ((a = UUSMPKnownExt (addit->subfname)) != -1 &&
00346 (b = UUSMPKnownExt (iter->subfname)) != -1)
00347 if (a != b) {
00348 iter = iter->NEXT;
00349 continue;
00350 }
00351
00352 flag = count = 0;
00353 fiter = iter->thisfile;
00354 temp = addit->thisfile;
00355 dest = NULL;
00356
00357 while (temp) {
00358 if (!(temp->data->uudet)) {
00359 temp = temp->NEXT;
00360 continue;
00361 }
00362
00363 while (fiter && fiter->partno < temp->partno) {
00364 dest = fiter;
00365 fiter = fiter->NEXT;
00366 }
00367 if (fiter && fiter->partno == temp->partno) {
00368 flag = 0;
00369 break;
00370 }
00371 else {
00372 flag = 1;
00373 count += ((dest) ? temp->partno - dest->partno - 1 : 0) +
00374 ((fiter) ? fiter->partno - temp->partno - 1 : 0);
00375 }
00376
00377 temp = temp->NEXT;
00378 }
00379 if (flag == 0 ||
00380 (pass == 0 && count > 0) ||
00381 (pass == 1 && count > 5)) {
00382 iter = iter->NEXT;
00383 continue;
00384 }
00385
00386 dest = iter->thisfile;
00387 fiter = addit->thisfile;
00388
00389 if (iter->filename == NULL && addit->filename != NULL)
00390 iter->filename = _FP_strdup (addit->filename);
00391
00392 if (addit->begin) iter->begin = 1;
00393 if (addit->end) iter->end = 1;
00394
00395 if (addit->mode != 0 && iter->mode == 0)
00396 iter->mode = addit->mode;
00397
00398 while (fiter) {
00399 flag = 0;
00400
00401 if (fiter->partno == iter->thisfile->partno ||
00402 (dest->NEXT != NULL && fiter->partno == dest->NEXT->partno)) {
00403 temp = fiter->NEXT;
00404 fiter->NEXT = NULL;
00405
00406 UUkillfile (fiter);
00407
00408 addit->thisfile= temp;
00409 fiter = temp;
00410 continue;
00411 }
00412 if (fiter->partno < iter->thisfile->partno) {
00413 temp = fiter->NEXT;
00414 fiter->NEXT = iter->thisfile;
00415 iter->thisfile = fiter;
00416 dest = fiter;
00417 addit->thisfile= temp;
00418 fiter = temp;
00419 }
00420 else if (dest->NEXT == NULL || fiter->partno < dest->NEXT->partno) {
00421 temp = fiter->NEXT;
00422 fiter->NEXT = dest->NEXT;
00423 dest->NEXT = fiter;
00424 addit->thisfile= temp;
00425 fiter = temp;
00426 }
00427 else {
00428 dest = dest->NEXT;
00429 }
00430 }
00431 break;
00432 }
00433 return iter;
00434 }
00435
00436 int UUEXPORT
00437 UUSmerge (int pass)
00438 {
00439 uulist *iter = UUGlobalFileList, *last=NULL, *res, *temp;
00440 int flag = 0;
00441
00442 while (iter) {
00443 if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
00444 last = iter;
00445 iter = iter->NEXT;
00446 continue;
00447 }
00448 if ((res = UU_smparts_r (iter, pass)) != NULL) {
00449 UUMessage (uuutil_id, __LINE__, UUMSG_MESSAGE,
00450 uustring (S_SMERGE_MERGED),
00451 (iter->subfname) ? iter->subfname : "",
00452 (res->subfname) ? res->subfname : "", pass);
00453
00454 temp = iter->NEXT;
00455 iter->NEXT = NULL;
00456 UUkilllist (iter);
00457
00458 flag++;
00459
00460 if (last == NULL) {
00461 UUGlobalFileList = temp;
00462 iter = temp;
00463 }
00464 else {
00465 last->NEXT = temp;
00466 iter = temp;
00467 }
00468
00469 continue;
00470 }
00471 last = iter;
00472 iter = iter->NEXT;
00473 }
00474
00475
00476
00477
00478
00479 UUCheckGlobalList ();
00480
00481 return flag;
00482 }
00483