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 unsigned int len; // length of file (not suporting 'big files' 2GB..)
21 unsigned int 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 fseek ( f, 0, SEEK_END );
35 fseek ( 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 fseek ( 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 fseek ( 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
74 } else if ( pos > PND_PXML_WINDOW_FRACTIONAL ) {
75 pos -= PND_PXML_WINDOW_FRACTIONAL;
76 readable = PND_PXML_WINDOW_SIZE;
78 readable = PND_PXML_WINDOW_SIZE - pos;
79 memset ( b + pos, '\0', PND_PXML_WINDOW_SIZE - pos );
85 // exeunt, with alarums
90 unsigned char pnd_pnd_accrue_pxml ( FILE *f, char *target, unsigned int maxlen ) {
91 char inbuf [ 1024 ]; // TBD: love all these assumptions? noob!
92 char *insert = target;
95 while ( fgets ( inbuf, 1023, f ) ) {
97 // copy inbuf onto end of target
99 strncpy ( insert, inbuf, maxlen );
100 // reduce counter for max size so we can avoid buffer overruns
101 l = strlen ( inbuf );
102 maxlen -= l; // reduce
103 insert += l; // increment
105 strncat ( target, inbuf, maxlen );
108 if ( strcasestr ( inbuf, PXML_TAGFOOT ) ) {
117 char *pnd_match_binbuf ( char *haystack, unsigned int maxlen, char *needle ) {
118 char *end = haystack + maxlen - strlen ( needle );
119 unsigned int needlelen = strlen ( needle );
121 while ( haystack < end ) {
123 if ( isprint(*haystack) ) {
125 if ( strncasecmp ( haystack, needle, needlelen ) == 0 ) {
126 //printf ( "haystack %s\n", haystack );
138 static unsigned char pnd_pnd_mountie ( char *pndrun, char *fullpath, char *unique_id, unsigned char do_mount ) {
155 printf ( " runscript: %s\n", pndrun );
156 printf ( " path: %s\n", fullpath );
157 printf ( " id: %s\n", unique_id );
160 memset ( argv, '\0', sizeof(char*) * 20 );
164 argv [ f++ ] = pndrun;
166 argv [ f++ ] = fullpath;
168 argv [ f++ ] = unique_id;
178 argv [ f++ ] = NULL; // for execv
183 for ( i = 0; i < f; i++ ) {
184 printf ( "exec's argv %u [ %s ]\n", i, argv [ i ] );
190 if ( ( f = fork() ) < 0 ) {
192 } else if ( f > 0 ) {
196 execv ( pndrun, argv );
199 // wait until mountscript actually completes
206 unsigned char pnd_pnd_mount ( char *pndrun, char *fullpath, char *unique_id ) {
207 return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 1 ) );
210 unsigned char pnd_pnd_unmount ( char *pndrun, char *fullpath, char *unique_id ) {
211 return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 0 ) );