/*---------------------------------------------------------------------------- U U B U F F E R A function for encoding a given buffer with the uuencode algorithm. Derived form a uuencoder for files written by Don Kneller: kneller@ucsfcgl.bitnet. Mark Koennecke, April 1998 -----------------------------------------------------------------------------*/ #include #include #include "fortify.h" #include #include #include "uubuffer.h" /*--------------------------------------------------------------------------*/ typedef struct _ReadBuf { char *pPtr; char *pCurrent; int iBufPtr; int iBufLen; } ReadBuf, *pReadBuf; /*--------------------------------------------------------------------------*/ static int ReadBytes(pReadBuf self, char *pBuffer, int iLen) { int iLeft; if (self->iBufPtr + iLen < self->iBufLen) { memcpy(pBuffer, &self->pPtr[self->iBufPtr], iLen); self->iBufPtr += iLen; self->pCurrent += iLen; return iLen; } else { iLeft = self->iBufLen - self->iBufPtr; if (iLeft == 0) { return 0; } memcpy(pBuffer, &self->pPtr[self->iBufPtr], iLeft); self->iBufPtr = self->iBufLen; self->pCurrent += iLeft; return iLeft; } } /*-------------------------------------------------------------------------*/ static int ReadPut(pReadBuf self, char c) { *(self->pCurrent) = c; self->iBufPtr++; self->pCurrent++; return 1; } /*--------------------------------------------------------------------------*/ static int ReadWrite(pReadBuf self, char *pText) { int i; for (i = 0; i < strlen(pText); i++) { ReadPut(self, pText[i]); } return 1; } /*-------------------------------------------------------------------------*/ /* ENC is the basic 1 character encoding function to make a char printing */ #define ENC(c) (((c) & 077) + ' ') static void OutDec(char *p, pReadBuf self) { int c1, c2, c3, c4; c1 = *p >> 2; c2 = ((p[0] << 4) & 060) | ((p[1] >> 4) & 017); c3 = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); c4 = p[2] & 077; /* original, replaced by code below for efficiency. Saves a couple of function call overhead. The profiler showed this as a bottleneck. ReadPut(self,ENC(c1)); ReadPut(self,ENC(c2)); ReadPut(self,ENC(c3)); ReadPut(self,ENC(c4)); */ *(self->pCurrent) = ENC(c1); self->pCurrent++; *(self->pCurrent) = ENC(c2); self->pCurrent++; *(self->pCurrent) = ENC(c3); self->pCurrent++; *(self->pCurrent) = ENC(c4); self->pCurrent++; self->iBufPtr += 4; } /*--------------------------------------------------------------------------*/ int UUencodeBuffer(void *pBuffer, int iBufLen, char *pName, void **pEncoded, int *iLength) { char pBuffel[80]; ReadBuf sRead, sWrite; int i, n; assert(pBuffer); assert(iBufLen > 0); /* set up read buffer */ sRead.pPtr = pBuffer; sRead.iBufPtr = 0; sRead.iBufLen = iBufLen; sRead.pCurrent = pBuffer; /* set up write buffer. uuencode increases size by 33%, we do 50% + a bit for newlines etc. */ iBufLen += iBufLen / 2; sWrite.pPtr = NULL; sWrite.pPtr = (char *) malloc((512 + iBufLen) * sizeof(char)); if (!sWrite.pPtr) { return 0; } memset(sWrite.pPtr, 0, (512 + iBufLen) * sizeof(char)); sWrite.iBufPtr = 0; sWrite.iBufLen = iBufLen + 512; sWrite.pCurrent = sWrite.pPtr; /* do the header */ ReadWrite(&sWrite, "begin 622 "); ReadWrite(&sWrite, pName); ReadWrite(&sWrite, " \r\n"); /* well, do it */ for (;;) { n = ReadBytes(&sRead, pBuffel, 45); if (n > 0) { ReadPut(&sWrite, ENC(n)); for (i = 0; i < n; i += 3) { OutDec(&pBuffel[i], &sWrite); } ReadWrite(&sWrite, "\r\n"); } else { break; } } /* finish the game */ ReadWrite(&sWrite, "end \r\n"); *pEncoded = sWrite.pPtr; *iLength = sWrite.iBufPtr; return 1; }