-/** Read an mbox
- */
+/********************************************************************************
+* mbox-helper/mbox-helper.c : read and parse an mbox file
+* ------------------------
+*
+* This file is part of the banana distribution
+* Copyright: See COPYING files that comes with this distribution
+********************************************************************************/
#define _GNU_SOURCE
#include <unistd.h>
/** Macros
*/
-#define LTRIM(pos) while (isspace(*pos)) { pos++; }
-#define STRTOLOWER(str, ptr) for (ptr = str ; *ptr ; ptr++) { *ptr = tolower(*ptr); }
+#define LTRIM(pos) while (isspace(*pos)) { ++pos; }
+#define STRTOLOWER(str, ptr) for (ptr = str ; *ptr ; ++ptr) { *ptr = tolower(*ptr); }
/** MBox pointer
*/
typedef struct
{
- FILE *fp; // File pointer
+ FILE *fp; // File pointer
long int lastLine; // Offset of the precedent line (-1 if invalid)
long int currentLine; // Offset of the current line
long int messageId; // Current message Id
MBox;
/** Open a mbox
+ * @param filename char* Path to the file to open
+ * @return NULL on error, a well initialized MBox structure pointer on success
*/
static MBox *openMBox(char *filename)
{
FILE *fp;
MBox *mbox;
- fp = fopen(filename, "r");
+ fp = fopen(filename, "r");
if (!fp) {
return NULL;
}
}
/** Read a line in a file
+ * @param mbox MBox the source mbox
+ * @return the read line
+ *
+ * This function do not only read the line, it does minimum parsing stuff and
+ * set the corresponding mbox structure flags
*/
static char *readLine(MBox *mbox)
{
mbox->lastLine = mbox->currentLine;
mbox->currentLine = ftell(mbox->fp);
mbox->isFrom_ = false;
-
+
if (!mbox->line) {
mbox->line = (char*)malloc(1001);
}
return mbox->line;
}
-#if 0 /* unused right now */
-/** Return to the last line
+/** Read a From_ line from the mbox
+ * the From_ line MUST be the current or the next one
*/
-static bool lastLine(MBox *mbox)
-{
- if (mbox->lastLine != -1) {
- fseek(mbox->fp, mbox->lastLine, SEEK_SET);
- mbox->lastLine = -1;
- readLine(mbox);
- return true;
- }
- return false;
-}
-#endif
-
static bool readFrom_(MBox *mbox)
{
if (!mbox->isFrom_) {
}
/** Read a message
+ * The message is not stored or returned, just skipped.
+ * If display is true, the message is printed on stdio
*/
static void readMessage(MBox *mbox, bool display)
{
}
/** Read the headers of a message
+ * Read the given headers of the current message of the given mbox
+ * @param mbox MBox source
+ * @param headers char** list of requested headers
+ * @param hdrsize int size of @ref headers
+ *
+ * THe headers are printed on stdio
*/
static void readHeaders(MBox *mbox, char **headers, int hdrsize)
{
char *current = NULL;
char *pos, *ptr;
int size, i;
-
+
if (!readFrom_(mbox)) {
return;
}
continue;
}
size = pos - mbox->line;
- for (i = 0 ; i < hdrsize ; i++) {
+ for (i = 0 ; i < hdrsize ; ++i) {
if ((int)strlen(headers[i]) == size && strcasestr(mbox->line, headers[i]) == mbox->line) {
current = (char*)malloc(size + 1);
strcpy(current, headers[i]);
- current[size] = '\0';
+ current[size] = '\0';
}
}
if (!current && !hdrsize) {
readLine(mbox);
}
-/** Go back to the beginning of the message
+/** Go back to the beginning of the current message
+ * @return true if the beginning of a message has been reached
*/
static bool rewindMessage(MBox *mbox)
{
}
/** Move to the given offset
+ * @param mbox MBox the source mbox
+ * @param offset int offset where to go
+ * @param idx int index of the message corresponding with the offset
+ * @return true if the given offset is the beginning of a message
*/
static bool goToOffset(MBox *mbox, int offset, int idx)
{
}
/** Move to the given message number
+ * @param mbox MBox the source mbox
+ * @param idx int the index of the message where to go
+ * @return true if the given message has been reached
*/
static bool goToMessage(MBox *mbox, int idx)
{
if (mbox->messageId > idx) {
- rewindMBox(mbox);
+ rewindMBox(mbox);
} else if(mbox->messageId == idx) {
rewindMessage(mbox);
return true;
}
-/** Display the program help
+/** Display the program usage help
*/
static void help(void)
{
/** Display an error message
* This function display the giver error, then show the program help and exit the program
+ * The memory must be cleared before calling this function
*/
static void error(const char *message)
{
char *endptr;
MBox *mbox;
+ // Parse command line
while ((c = getopt(argc, argv, ":bcdp:hm:f:")) != -1) {
switch (c) {
case 'f':
if (endptr == optarg) {
error("invalid message id");
}
- if (*endptr != ':') {
+ if (*endptr != ':' || !*(endptr+1)) {
lmid = fmid;
} else {
lmid = atoi(endptr + 1);
case 'p':
if ((endptr = strchr(optarg, ':')) != NULL) {
pmid = strtol(optarg, &endptr, 10);
- if (*endptr != ':') {
+ if (*endptr != ':' || !*(endptr+1)) {
error("invalid position couple given");
}
pos = atoi(endptr + 1);
break;
}
}
-
+
+ // Check command line arguments consistence
if (!filename) {
error("no file defined");
}
setlocale(LC_ALL, "C");
-
+
headerNb = argc - optind;
headers = (argv + optind);
for (i = 0 ; i < headerNb ; i++) {
mbox = openMBox(filename);
if (!mbox) {
- fprintf(stderr, "can't open file '%s'", filename);
+ fprintf(stderr, "can't open file '%s'\n", filename);
+ return 1;
}
if ((fmid >= pmid || fmid == -1) && pos) {
if (!goToOffset(mbox, pos, pmid)) {
fprintf(stderr, "Offset %d do not match with a message beginning\n", pos);
rewindMBox(mbox);
- }
+ }
}
+
+ // Do requested stuff
switch (action) {
case 'b':
if (fmid == -1) {
- fprintf(stderr, "you have to define a message number");
+ fprintf(stderr, "you have to define a message number\n");
break;
}
goToMessage(mbox, fmid);
break;
case 'd':
if (fmid == -1) {
- fprintf(stderr, "you have to define a message number");
+ fprintf(stderr, "you have to define a message number\n");
break;
}
for (i = fmid ; i <= lmid ; i++) {