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