diff --git a/utils/mnetftn/Makefile b/utils/mnetftn/Makefile index 46cf485..33580cc 100644 --- a/utils/mnetftn/Makefile +++ b/utils/mnetftn/Makefile @@ -3,19 +3,28 @@ CFLAGS=-I/usr/local/include -I../../deps/ DEPS = mnettoftn.c JAMLIB = ../../deps/jamlib/jamlib.a OBJ = mnettoftn.o +OBJ2 = ftntomnet.o +UUID = ../../deps/libuuid/.libs/libuuid.a -all: mnettoftn +all: mnettoftn ftntomnet %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) +$(UUID): + cd ../deps/libuuid/ && ./configure + cd ../deps/libuuid/ && $(MAKE) + $(JAMLIB): cd ../../deps/jamlib && make -f Makefile.linux +ftntomnet: $(OBJ2) $(JAMLIB) $(UUID) + $(CC) -o ftntomnet $^ $(CFLAGS) -L/usr/local/lib + mnettoftn: $(OBJ) $(JAMLIB) $(CC) -o mnettoftn $^ $(CFLAGS) -L/usr/local/lib .PHONY: clean clean: - rm -f $(OBJ) mnettoftn + rm -f $(OBJ) mnettoftn $(OBJ2) ftntomnet diff --git a/utils/mnetftn/ftntomnet.c b/utils/mnetftn/ftntomnet.c new file mode 100644 index 0000000..5a8fe74 --- /dev/null +++ b/utils/mnetftn/ftntomnet.c @@ -0,0 +1,401 @@ +#include +#include +#include +#include +#include +#include +#include "libuuid/uuid.h" +#include "jamlib/jam.h" + +char *baseoutdir = NULL; + +struct msgarea_t { + int id; + int hub; + char *basedir; + int *links; + int link_count; +}; + +struct msg_t { + int area; + char from[32]; + char to[32]; + char subject[64]; + uint32_t timedate; + int oaddr; + int daddr; + int type; + char reply[36]; +} __attribute__ ((packed)); + +struct msgarea_t **areas; +int area_count; +int mynode = 0; +int hubnode = 0; +int imhub = 0; + +s_JamBase *open_jam_base(char *path) { + int ret; + s_JamBase *jb; + + ret = JAM_OpenMB((char *)path, &jb); + + if (ret != 0) { + if (ret == JAM_IO_ERROR) { + free(jb); + ret = JAM_CreateMB((char *)path, 1, &jb); + if (ret != 0) { + free(jb); + return NULL; + } + } else { + free(jb); + return NULL; + } + } + return jb; +} + +size_t trimwhitespace(char *out, size_t len, const char *str) { + if(len == 0) + return 0; + + const char *end; + size_t out_size; + + // Trim leading space + while(isspace((unsigned char)*str)) str++; + + if(*str == 0) { + *out = 0; + return 1; + } + + // Trim trailing space + end = str + strlen(str) - 1; + while(end > str && isspace((unsigned char)*end)) end--; + end++; + + // Set output size to minimum of trimmed string length and buffer size minus 1 + out_size = (end - str) < len-1 ? (end - str) : len-1; + + // Copy trimmed string and add null terminator + memcpy(out, str, out_size); + out[out_size] = 0; + + return out_size; +} + +int parse_config_file(char *filename) { + FILE *fptr; + char buffer[256]; + char bufferw[256]; + char *ptr; + struct msgarea_t *newarea; + + area_count = 0; + + fptr = fopen(filename, "r"); + if (!fptr) { + return 0; + } + + fgets(buffer, 256, fptr); + while (!feof(fptr)) { + if (buffer[0] != ';') { + if (buffer[strlen(buffer) - 1] == '\n'){ + buffer[strlen(buffer) - 1] = '\0'; + + if (strncasecmp(buffer, "MYNODE", 6) == 0) { + trimwhitespace(bufferw, 256, &buffer[7]); + mynode = atoi(bufferw); + } else if (strncasecmp(buffer, "IMHUB", 5) == 0) { + trimwhitespace(bufferw, 256, &buffer[6]); + if (strcasecmp(bufferw, "TRUE") == 0) { + imhub = 1; + } + } else if (strncasecmp(buffer, "UPLINK", 6) == 0) { + trimwhitespace(bufferw, 256, &buffer[7]); + hubnode = atoi(bufferw); + } else if (strncasecmp(buffer, "OUTDIR", 6) == 0) { + trimwhitespace(bufferw, 256, &buffer[7]); + baseoutdir = strdup(bufferw); + } else if (strncasecmp(buffer, "MSGAREA", 7) == 0) { + newarea = NULL; + ptr = strtok(&buffer[8], ","); + + if (ptr != NULL) { + newarea = (struct msgarea_t *)malloc(sizeof(struct msgarea_t)); + trimwhitespace(bufferw, 256, ptr); + newarea->id = atoi(bufferw); + newarea->link_count = 0; + ptr = strtok(NULL, ","); + + if (ptr != NULL) { + trimwhitespace(bufferw, 256, ptr); + newarea->hub = atoi(bufferw); + ptr = strtok(NULL, ","); + if (ptr != NULL) { + + trimwhitespace(bufferw, 256, ptr); + newarea->basedir = strdup(bufferw); + ptr = strtok(NULL, ","); + while (ptr != NULL) { + trimwhitespace(bufferw, 256, ptr); + if (newarea->link_count == 0) { + newarea->links = (int *)malloc(sizeof(int)); + } else { + newarea->links = (int *)realloc(newarea->links, sizeof(int) * (newarea->link_count + 1)); + } + newarea->links[newarea->link_count] = atoi(bufferw); + newarea->link_count++; + ptr = strtok(NULL, ","); + } + } + } + } + if (newarea != NULL) { + if (area_count == 0) { + areas = (struct msgarea_t **)malloc(sizeof(struct msgarea_t *)); + } else { + areas = (struct msgarea_t **)realloc(areas, sizeof(struct msgarea_t *) * (area_count + 1)); + } + areas[area_count] = newarea; + area_count++; + } + } + } else { + fclose(fptr); + return 0; + } + } + fgets(buffer, 256, fptr); + } + + fclose(fptr); + return 1; +} + +int export_messages(int area) { + s_JamBase *jb; + s_JamBaseHeader jbh; + s_JamMsgHeader jmh; + s_JamSubPacket* jsp; + + FILE *fptr; + + char buffer[PATH_MAX]; + + int i; + int z; + int len; + int n; + int scanned = 0; + + struct msg_t msg; + + char *body; + struct stat st; + uuid_t myuuid; + char msgid[37]; + + jb = open_jam_base(areas[area]->basedir); + if (!jb) { + return 0; + } + JAM_ReadMBHeader(jb, &jbh); + if (jbh.ActiveMsgs > 0) { + for (i=0;iNumFields;z++) { + if (jsp->Fields[z]->LoID == JAMSFLD_SUBJECT) { + if (jsp->Fields[z]->DatLen > 63) { + len = 64; + } else { + len = jsp->Fields[z]->DatLen; + } + memcpy(msg.subject, jsp->Fields[z]->Buffer, len); + } + if (jsp->Fields[z]->LoID == JAMSFLD_SENDERNAME) { + if (jsp->Fields[z]->DatLen > 61) { + len = 32; + } else { + len = jsp->Fields[z]->DatLen; + } + memcpy(msg.from, jsp->Fields[z]->Buffer, len); + } + if (jsp->Fields[z]->LoID == JAMSFLD_RECVRNAME) { + if (jsp->Fields[z]->DatLen > 61) { + len = 32; + } else { + len = jsp->Fields[z]->DatLen; + } + memcpy(msg.to, jsp->Fields[z]->Buffer, len); + } + } + msg.oaddr = mynode; + msg.timedate = jmh.DateWritten; + body = (char *)malloc(jmh.TxtLen + 1); + memset(body, 0, jmh.TxtLen + 1); + JAM_ReadMsgText(jb, jmh.TxtOffset, jmh.TxtLen, (char *)body); + + jmh.Attribute |= JAM_MSG_SENT; + + memset(msgid, 0, 37); + uuid_generate(myuuid); + uuid_unparse_lower(myuuid, msgid); + + while (1) { + z = JAM_LockMB(jb, 100); + if (z == 0) { + break; + } else if (z == JAM_LOCK_FAILED) { + sleep(1); + } else { + free(body); + JAM_DelSubPacket(jsp); + JAM_CloseMB(jb); + free(jb); + fprintf(stderr, "Error locking JAM base!\n"); + return scanned; + } + } + n =JAM_ChangeMsgHeader(jb, i, &jmh); + + snprintf(buffer, PATH_MAX, "%s.msgids", areas[area]->basedir); + fptr = fopen(buffer, "a"); + if (!fptr) { + fprintf(stderr, "Error writing msgid to base\n"); + } else { + fputs(msgid, fptr); + fputc('\n', fptr); + fclose(fptr); + } + + if (n != 0) { + fprintf(stderr, "Error updating message header %d %d\n", n, JAM_Errno(jb)); + } + JAM_UnlockMB(jb); + JAM_DelSubPacket(jsp); + + msg.area = areas[area]->id; + msg.type = 0; + if (areas[area]->hub == mynode) { + for (n = 0; n < areas[area]->link_count; n++) { + if (imhub) { + snprintf(buffer, PATH_MAX, "%s/%d/", baseoutdir, areas[area]->links[n]); + } else { + snprintf(buffer, PATH_MAX, "%s/%d/", baseoutdir, hubnode); + } + if (stat(buffer, &st) != 0) { + if (mkdir(buffer, 0755) != 0) { + fprintf(stderr, "Error making directory %s\n", buffer); + continue; + } + } + if (imhub) { + snprintf(buffer, PATH_MAX, "%s/%d/%d-%s.message", baseoutdir, areas[area]->links[n], areas[area]->links[n], msgid); + } else { + snprintf(buffer, PATH_MAX, "%s/%d/%d-%s.message", baseoutdir, hubnode, areas[area]->links[n], msgid); + } + msg.daddr = areas[area]->links[n]; + fptr = fopen(buffer, "wb"); + if (fptr == NULL) { + fprintf(stderr, "Error creating file %s\n", buffer); + continue; + } + + fwrite(&msg, sizeof(struct msg_t), 1, fptr); + fwrite(body, strlen(body), 1, fptr); + fclose(fptr); + } + } else { + if (imhub) { + snprintf(buffer, PATH_MAX, "%s/%d/", baseoutdir, areas[area]->hub); + } else { + snprintf(buffer, PATH_MAX, "%s/%d/", baseoutdir, hubnode); + } + if (stat(buffer, &st) != 0) { + if (mkdir(buffer, 0755) != 0) { + fprintf(stderr, "Error making directory %s\n", buffer); + continue; + } + } + if (imhub) { + snprintf(buffer, PATH_MAX, "%s/%d/%d-%s.message", baseoutdir, areas[area]->hub, areas[area]->hub, msgid); + } else { + snprintf(buffer, PATH_MAX, "%s/%d/%d-%s.message", baseoutdir, hubnode, areas[area]->hub, msgid); + } + + msg.daddr = areas[area]->hub; + fptr = fopen(buffer, "wb"); + if (fptr == NULL) { + fprintf(stderr, "Error creating file %s\n", buffer); + continue; + } + + fwrite(&msg, sizeof(struct msg_t), 1, fptr); + fwrite(body, strlen(body), 1, fptr); + fclose(fptr); + } + scanned++; + } + } + } + JAM_CloseMB(jb); + free(jb); + + return scanned; +} + +int main(int argc, char **argv) { + int i; + int l; + + if (argc < 2) { + fprintf(stderr, "Usage ./mnetscan mnet.cfg\n"); + return -1; + } + + if (!parse_config_file(argv[1])) { + fprintf(stderr, "Error parsing config file: %s\n", argv[1]); + return -1; + } + + if (baseoutdir == NULL) { + fprintf(stderr, "OUTDIR must be defined\n"); + return -1; + } + + printf("Out Base Dir: %s\n", baseoutdir); + + for (i=0;iid); + printf(" - path %s\n", areas[i]->basedir); + printf(" - links: "); + for (l=0;llink_count;l++) { + printf("%d, ", areas[i]->links[l]); + } + printf("\n"); + + printf("\nExported %d messages\n", export_messages(i)); + } + return 0; +} \ No newline at end of file diff --git a/utils/mnetftn/mnettoftn.c b/utils/mnetftn/mnettoftn.c index 3a156c2..3a31dff 100644 --- a/utils/mnetftn/mnettoftn.c +++ b/utils/mnetftn/mnettoftn.c @@ -493,7 +493,6 @@ int import(char *filename) { } } - JAM_ClearMsgHeader(&jmh); jmh.DateWritten = msg.timedate; jmh.Attribute |= JAM_MSG_TYPEECHO;