/* Read an arbitrarily long line of text from STREAM into LINEBUFFER. * Consider lines to be terminated by DELIMITER. * Keep the delimiter. * Do not NUL-terminate; Therefore the stream can contain NUL bytes, and * the length (including the delimiter) is returned in linebuffer->length. * Return NULL when stream is empty or upon error. * Otherwise, return LINEBUFFER. */ struct LineBuffer *readlinebuffer(struct LineBuffer *linebuffer, MY_FILE *stream, char delimiter) { int c; char *buffer = linebuffer->buffer; char *p = linebuffer->buffer; char *end = buffer + linebuffer->size; if(my_feof(stream)) return NULL; do { c = my_fgetc(stream); if(c == EOF) { // Return NULL when stream is empty or upon error if(p == buffer || my_ferror(stream)) return NULL; // append DELIMITER if it's the last line of a file that ends in a character other than DELIMITER. if(p[-1] != delimiter) c = delimiter; } // Check if we need to allocate more space if(p == end) { size_t oldsize = linebuffer->size; linebuffer->size += BUFF_SIZE_INC; buffer = realloc(buffer, linebuffer->size); p = buffer + oldsize; linebuffer->buffer = buffer; end = buffer + linebuffer->size; } *p++ = c; } while(c != delimiter); linebuffer->length = p - buffer; return linebuffer; }
int encfile(struct my_FILE* fin, struct aes *ctx) { unsigned char inbuf[16], outbuf[16]; long int flen; unsigned long i=0, l=0; fillrand(outbuf, 16); /* set an IV for CBC mode */ flen = fin->size; // fseek(fin, 0, SEEK_END); /* get the length of the file */ // fgetpos(fin, (fpos_t*)&flen); /* and then reset to start */ // fseek(fin, 0, SEEK_SET); // fwrite(outbuf, 1, 16, fout); /* write the IV to the output */ fillrand(inbuf, 1); /* make top 4 bits of a byte random */ l = 15; /* and store the length of the last */ /* block in the lower 4 bits */ inbuf[0] = ((char)flen & 15) | (inbuf[0] & ~15); _Pragma( "loopbound min 1961 max 1961" ) while(!my_feof(fin)) /* loop to encrypt the input file */ { /* input 1st 16 bytes to buf[1..16] */ i = my_fread(inbuf + 16 - l, 1, l, fin); /* on 1st round byte[0] */ /* is the length code */ if(i < l) break; /* if end of the input file reached */ _Pragma( "loopbound min 16 max 16" ) for(i = 0; i < 16; ++i) /* xor in previous cipher text */ inbuf[i] ^= outbuf[i]; encrypt(inbuf, outbuf, ctx); /* and do the encryption */ // if(fwrite(outbuf, 1, 16, fout) != 16) { // printf("Error writing to output file: %s\n", fn); // return -7; // } /* in all but first round read 16 */ l = 16; /* bytes into the buffer */ } /* except for files of length less than two blocks we now have one */ /* byte from the previous block and 'i' bytes from the current one */ /* to encrypt and 15 - i empty buffer positions. For files of less */ /* than two blocks (0 or 1) we have i + 1 bytes and 14 - i empty */ /* buffer position to set to zero since the 'count' byte is extra */ if(l == 15) /* adjust for extra byte in the */ ++i; /* in the first block */ if(i) /* if bytes remain to be output */ { _Pragma( "loopbound min 6 max 6" ) while(i < 16) /* clear empty buffer positions */ inbuf[i++] = 0; _Pragma( "loopbound min 16 max 16" ) for(i = 0; i < 16; ++i) /* xor in previous cipher text */ inbuf[i] ^= outbuf[i]; encrypt(inbuf, outbuf, ctx); /* encrypt and output it */ // if(fwrite(outbuf, 1, 16, fout) != 16) { // printf("Error writing to output file: %s\n", fn); // return -8; // } } return 0; }