Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../cmd.h"
4 : #include "../../fzp.h"
5 : #include "../../hexmap.h"
6 : #include "../../iobuf.h"
7 : #include "../../log.h"
8 : #include "../../protocol2/blk.h"
9 : #include "rblk.h"
10 :
11 : #define RBLK_MAX 10
12 :
13 : // For retrieving stored data.
14 : struct rblk
15 : {
16 : char *datpath;
17 : struct iobuf readbuf[DATA_FILE_SIG_MAX];
18 : uint16_t readbuflen;
19 : };
20 :
21 : static struct rblk *rblks=NULL;
22 :
23 6 : int rblk_init(void)
24 : {
25 6 : rblks=(struct rblk *)calloc_w(RBLK_MAX, sizeof(struct rblk), __func__);
26 6 : if(!rblks) return -1;
27 6 : return 0;
28 : }
29 :
30 7 : void rblk_free(void)
31 : {
32 14 : if(!rblks) return;
33 60 : for(int i=0; i<RBLK_MAX; i++)
34 : {
35 60 : free_w(&rblks[i].datpath);
36 245820 : for(int j=0; j<DATA_FILE_SIG_MAX; j++)
37 245760 : iobuf_free_content(&rblks[i].readbuf[j]);
38 : }
39 6 : free_v((void **)&rblks);
40 : }
41 :
42 56 : static int load_rblk(struct rblk *rblks, int ind, const char *datpath)
43 : {
44 : int r;
45 56 : int ret=-1;
46 56 : int done=0;
47 56 : struct fzp *fzp=NULL;
48 : struct iobuf rbuf;
49 :
50 56 : iobuf_init(&rbuf);
51 :
52 56 : free_w(&rblks[ind].datpath);
53 56 : if(!(rblks[ind].datpath=strdup_w(datpath, __func__)))
54 : goto end;
55 :
56 56 : logp("swap %d to: %s\n", ind, datpath);
57 :
58 56 : if(!(fzp=fzp_open(datpath, "rb")))
59 : goto end;
60 360 : for(r=0; r<DATA_FILE_SIG_MAX; r++)
61 : {
62 416 : switch(iobuf_fill_from_fzp_data(&rbuf, fzp))
63 : {
64 360 : case 0: if(rbuf.cmd!=CMD_DATA)
65 : {
66 0 : logp("unknown cmd in %s: %c\n",
67 : __func__, rbuf.cmd);
68 0 : goto end;
69 : }
70 360 : iobuf_free_content(&rblks[ind].readbuf[r]);
71 360 : iobuf_move(&rblks[ind].readbuf[r], &rbuf);
72 360 : continue;
73 : case 1: done++;
74 : break;
75 : default: goto end;
76 : }
77 : if(done) break;
78 : }
79 56 : rblks[ind].readbuflen=r;
80 56 : ret=0;
81 : end:
82 56 : fzp_close(&fzp);
83 56 : return ret;
84 : }
85 :
86 348 : static struct rblk *get_rblk(struct rblk *rblks, const char *datpath)
87 : {
88 : static int current_ind=0;
89 : static int last_swap_ind=0;
90 348 : int ind=current_ind;
91 :
92 : while(1)
93 : {
94 641 : if(!rblks[ind].datpath)
95 : {
96 26 : if(load_rblk(rblks, ind, datpath)) return NULL;
97 26 : last_swap_ind=ind;
98 26 : current_ind=ind;
99 26 : return &rblks[current_ind];
100 : }
101 615 : else if(!strcmp(rblks[ind].datpath, datpath))
102 : {
103 292 : current_ind=ind;
104 292 : return &rblks[current_ind];
105 : }
106 323 : ind++;
107 323 : if(ind==RBLK_MAX) ind=0;
108 323 : if(ind==current_ind)
109 : {
110 : // Went through all RBLK_MAX entries.
111 : // Replace the oldest one.
112 30 : ind=last_swap_ind+1;
113 30 : if(ind==RBLK_MAX) ind=0;
114 30 : if(load_rblk(rblks, ind, datpath)) return NULL;
115 30 : last_swap_ind=ind;
116 30 : current_ind=ind;
117 30 : return &rblks[current_ind];
118 : }
119 : }
120 : }
121 :
122 348 : int rblk_retrieve_data(const char *datpath, struct blk *blk)
123 : {
124 : static char fulldatpath[256]="";
125 : uint16_t datno;
126 : struct rblk *rblk;
127 :
128 348 : snprintf(fulldatpath, sizeof(fulldatpath), "%s/%s", datpath,
129 : uint64_to_savepathstr_with_sig_uint(blk->savepath, &datno));
130 :
131 348 : if(!(rblk=get_rblk(rblks, fulldatpath)))
132 : {
133 : return -1;
134 : }
135 :
136 : // printf("lookup: %s (%s)\n", fulldatpath, cp);
137 348 : if(datno>rblk->readbuflen)
138 : {
139 0 : logp("dat index %d is greater than readbuflen: %d\n",
140 : datno, rblk->readbuflen);
141 0 : return -1;
142 : }
143 348 : blk->data=rblk->readbuf[datno].buf;
144 348 : blk->length=rblk->readbuf[datno].len;
145 : // printf("length: %d\n", blk->length);
146 :
147 348 : return 0;
148 : }
|