--- /dev/null
+/*
+ * extract elecard efp files
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ * build: gcc -Wall efp_extract -o efp_extract
+ * usage: ./efp_extract file.efp
+ * chmod 640 file_??
+ *
+ * based on info from Muart232
+ * http://www.mikrocontroller.net/topic/210759
+ *
+ * elecard:
+ * http://www.elecard.com/forum/index.php?topic=4174.0
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int getbytes(int fd,char *buf,int len) {
+
+ int cnt,ret;
+
+ cnt=len;
+ while(cnt) {
+ ret=read(fd,buf+len-cnt,cnt);
+ cnt-=ret;
+ }
+
+ return 0;
+}
+
+int hexprint(char *buf,int len) {
+
+ int i;
+
+ for(i=0;i<len;i++)
+ printf("%02x ",*(buf+i));
+ printf("\n");
+
+ return 0;
+
+}
+
+int main(int argc,char **argv) {
+
+ int ret,cnt,i,fd,wfd;
+ char buf[128];
+ int nof;
+ unsigned int index[16],offset[16],len[16],wtf[16];
+ char filename[128];
+ char *map;
+
+ fd=open(argv[1],O_RDONLY);
+ if(fd<=0) {
+ perror("fd open");
+ return fd;
+ }
+
+ lseek(fd,12,SEEK_CUR);
+ // ignore first 12 bytes
+
+ getbytes(fd,buf,4);
+ nof=*((unsigned int *)buf);
+
+ printf("number of files: %d\n",nof);
+
+ lseek(fd,6,SEEK_CUR);
+
+ for(i=0;i<nof;i++) {
+
+ getbytes(fd,buf,4);
+ index[i]=*((unsigned int *)buf);
+
+ getbytes(fd,buf,4);
+ wtf[i]=*((unsigned int *)buf);
+
+ getbytes(fd,buf,4);
+ len[i]=*((unsigned int *)buf);
+
+ getbytes(fd,buf,4);
+ offset[i]=*((unsigned int *)buf);
+
+ lseek(fd,8,SEEK_CUR);
+ // ignore
+
+ printf("file %u:\n",index[i]);
+ printf(" - wtf: %u\n",wtf[i]);
+ printf(" - len: %u\n",len[i]);
+ printf(" - offset: %u\n",offset[i]);
+ printf(" - next estimated offset: %u\n",len[i]+offset[i]);
+
+ }
+
+ printf("mapping file into memory ...\n");
+ map=mmap(0,offset[nof-1]+len[nof-1],PROT_READ,MAP_SHARED,fd,0);
+
+ for(i=0;i<nof;i++) {
+
+ snprintf(filename,128,"file_%02d",index[i]);
+
+ wfd=open(filename,O_WRONLY|O_CREAT);
+ if(wfd<=0) {
+ perror("wfd open");
+ return wfd;
+ }
+
+ cnt=len[i];
+ while(cnt) {
+ ret=write(wfd,map+offset[i]+len[i]-cnt,cnt);
+ cnt-=ret;
+ }
+
+ close(wfd);
+
+ }
+
+ close(fd);
+
+ return 0;
+
+}