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 316 : 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 316 : int ind=current_ind;
91 :
92 : while(1)
93 : {
94 609 : 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 583 : else if(!strcmp(rblks[ind].datpath, datpath))
102 : {
103 260 : current_ind=ind;
104 260 : 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 316 : char *rblk_get_fulldatpath(const char *datpath,
123 : struct blk *blk, uint16_t *datno)
124 : {
125 : static char fulldatpath[256]="";
126 316 : snprintf(fulldatpath, sizeof(fulldatpath), "%s/%s", datpath,
127 : uint64_to_savepathstr_with_sig_uint(blk->savepath, datno));
128 316 : return fulldatpath;
129 : }
130 :
131 316 : int rblk_retrieve_data(const char *fulldatpath,
132 : struct blk *blk, uint16_t datno)
133 : {
134 : struct rblk *rblk;
135 :
136 316 : if(!(rblk=get_rblk(rblks, fulldatpath)))
137 : {
138 : return -1;
139 : }
140 :
141 : // printf("lookup: %s (%s)\n", fulldatpath, cp);
142 316 : if(datno>rblk->readbuflen)
143 : {
144 0 : logp("dat index %d is greater than readbuflen: %d\n",
145 : datno, rblk->readbuflen);
146 0 : return -1;
147 : }
148 316 : blk->data=rblk->readbuf[datno].buf;
149 316 : blk->length=rblk->readbuf[datno].len;
150 : // printf("length: %d\n", blk->length);
151 :
152 316 : return 0;
153 : }
|