2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <ctype.h> /* for isprint */
5 #include <unistd.h> /* for fork/exec */
6 #include <sys/types.h> /* for wait */
7 #include <sys/wait.h> /* for wait */
10 #include <string.h> /* for making strcasestr happy */
12 #include "pnd_container.h"
15 #include "pnd_pndfiles.h"
17 unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
19 char *match; // match within buffer
20 off_t len; // length of file (supporting 'big files' 2GB+)
21 off_t pos; // current tape head
22 unsigned int readable; // amount to read (for small files/chunks)
24 b = malloc ( PND_PXML_WINDOW_SIZE + 1 );
30 memset ( b, '\0', PND_PXML_WINDOW_SIZE + 1 );
32 // determine length of file
33 fseeko ( f, 0, SEEK_END );
35 fseeko ( f, 0, SEEK_SET );
37 /* ready to scan through the file, backwards
41 if ( len <= PND_PXML_WINDOW_SIZE ) {
45 pos = len - PND_PXML_WINDOW_SIZE;
46 readable = PND_PXML_WINDOW_SIZE;
51 //printf ( "find pxml; pos %u readable %u\n", pos, readable );
53 // seek into this blocks position
54 fseeko ( f, pos, SEEK_SET );
57 fread ( b, 1, readable, f );
59 // find the head tag here? now, there are serious heavy duty algorithyms for locating
60 // strings within an arbitrary buffer. Thats needs to be done. This is the worst
61 // performing brute force strategy here.
62 if ( ( match = pnd_match_binbuf ( b, readable, PXML_TAGHEAD ) ) ) {
63 fseeko ( f, pos + ( match - b ), SEEK_SET );
64 //printf ( " match found at %u\n", pos + ( match - b ) );
69 // no match, so we need to back up another chunk; if we can't
70 // back up that much, we're on our last check. if we can't back
71 // up at all, we've already been here and time to fail
75 } else if ( pos > PND_PXML_WINDOW_FRACTIONAL ) { // lots of space to back-seek
76 pos -= PND_PXML_WINDOW_FRACTIONAL;
77 readable = PND_PXML_WINDOW_SIZE;
79 // at some point when back-seeking, we just give up; we could seek through
80 // whole file (and if someone has gone and broken a pnd-file, the behaviour is
81 // 'undefined' .. but lets be kind in case that guy then distributes the broken
82 // file around. So we backseek to a point, but stop after xKB backwards?
83 if ( len - pos > (500*1024) ) {
87 } else { // can only backseek less than the window-size
88 readable = PND_PXML_WINDOW_SIZE - pos;
89 memset ( b + pos, '\0', PND_PXML_WINDOW_SIZE - pos );
95 // exeunt, with alarums
100 unsigned char pnd_pnd_accrue_pxml ( FILE *f, char *target, unsigned int maxlen ) {
101 char inbuf [ 1024 ]; // TBD: love all these assumptions? noob!
102 char *insert = target;
105 while ( fgets ( inbuf, 1023, f ) ) {
107 // copy inbuf onto end of target
109 strncpy ( insert, inbuf, maxlen );
110 // reduce counter for max size so we can avoid buffer overruns
111 l = strlen ( inbuf );
112 maxlen -= l; // reduce
113 insert += l; // increment
115 strncat ( target, inbuf, maxlen );
118 if ( strcasestr ( inbuf, PXML_TAGFOOT ) ) {
127 char *pnd_match_binbuf ( char *haystack, unsigned int maxlen, char *needle ) {
128 char *end = haystack + maxlen - strlen ( needle );
129 unsigned int needlelen = strlen ( needle );
131 while ( haystack < end ) {
133 if ( isprint(*haystack) ) {
135 if ( strncasecmp ( haystack, needle, needlelen ) == 0 ) {
136 //printf ( "haystack %s\n", haystack );
148 static unsigned char pnd_pnd_mountie ( char *pndrun, char *fullpath, char *unique_id, unsigned char do_mount ) {
165 printf ( " runscript: %s\n", pndrun );
166 printf ( " path: %s\n", fullpath );
167 printf ( " id: %s\n", unique_id );
170 memset ( argv, '\0', sizeof(char*) * 20 );
174 argv [ f++ ] = pndrun;
176 argv [ f++ ] = fullpath;
178 argv [ f++ ] = unique_id;
188 argv [ f++ ] = NULL; // for execv
193 for ( i = 0; i < f; i++ ) {
194 printf ( "exec's argv %u [ %s ]\n", i, argv [ i ] );
200 if ( ( f = fork() ) < 0 ) {
202 } else if ( f > 0 ) {
206 execv ( pndrun, argv );
209 // wait until mountscript actually completes
211 waitpid ( f, &status, 0 /* options */ );
216 unsigned char pnd_pnd_mount ( char *pndrun, char *fullpath, char *unique_id ) {
217 return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 1 ) );
220 unsigned char pnd_pnd_unmount ( char *pndrun, char *fullpath, char *unique_id ) {
221 return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 0 ) );