1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 00    UFS Store Dump Tool */
10 
11 #include "squid.h"
12 #include "Generic.h"
13 #include "md5.h"
14 #include "mgr/Registration.h"
15 #include "Store.h"
16 #include "store_key_md5.h"
17 #include "StoreMeta.h"
18 #include "StoreMetaUnpacker.h"
19 
20 #undef malloc
21 #undef free
22 
23 #include <cassert>
24 #include <iostream>
25 #include <stdexcept>
26 
27 /* stub functions for parts of squid not factored to be dynamic yet */
28 void
eventAdd(const char * name,EVH * func,void * arg,double when,int,bool cbdata)29 eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata)
30 {}
31 
32 // required by storeKeyPublicByRequest*
33 // XXX: what pulls in storeKeyPublicByRequest?
urlCanonical(HttpRequest *)34 const char *urlCanonical(HttpRequest *) { assert(false); return NULL; }
35 
36 void
storeAppendPrintf(StoreEntry * e,const char * fmt,...)37 storeAppendPrintf(StoreEntry * e, const char *fmt,...)
38 {
39     va_list args;
40     va_start(args, fmt);
41 
42     assert(false);
43 
44     va_end(args);
45 }
46 
47 void
RegisterAction(char const * action,char const * desc,OBJH * handler,int pw_req_flag,int atomic)48 Mgr::RegisterAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) {}
49 
50 /* MinGW needs also a stub of death() */
51 void
death(int sig)52 death(int sig)
53 {
54     std::cout << "Fatal: Signal " <<  sig;
55     exit(1);
56 }
57 
58 void
fatal(const char * message)59 fatal(const char *message)
60 {
61     fprintf(stderr, "FATAL: %s\n", message);
62     exit(1);
63 }
64 
65 /* end stub functions */
66 
67 struct MetaStd {
68     time_t timestamp;
69     time_t lastref;
70     time_t expires;
71     time_t lastmod;
72     size_t swap_file_sz;
73     uint16_t refcount;
74     uint16_t flags;
75 };
76 
77 struct MetaStdLfs {
78     time_t timestamp;
79     time_t lastref;
80     time_t expires;
81     time_t lastmod;
82     uint64_t swap_file_sz;
83     uint16_t refcount;
84     uint16_t flags;
85 };
86 
87 struct DumpStoreMeta : public unary_function<StoreMeta, void> {
DumpStoreMetaDumpStoreMeta88     DumpStoreMeta() {}
89 
operator ()DumpStoreMeta90     void operator()(StoreMeta const &x) {
91         switch (x.getType()) {
92 
93         case STORE_META_KEY:
94             std::cout << "MD5: " << storeKeyText((const cache_key *)x.value) << std::endl;
95             break;
96 
97         case STORE_META_STD:
98             std::cout << "STD, Size:" << ((struct MetaStd*)x.value)->swap_file_sz <<
99                       " Flags: 0x" << std::hex << ((struct MetaStd*)x.value)->flags << std::dec <<
100                       " Refcount: " << ((struct MetaStd*)x.value)->refcount <<
101                       std::endl;
102             break;
103 
104         case STORE_META_STD_LFS:
105             std::cout << "STD_LFS, Size: " << ((struct MetaStdLfs*)x.value)->swap_file_sz <<
106                       " Flags: 0x" << std::hex << ((struct MetaStdLfs*)x.value)->flags << std::dec <<
107                       " Refcount: " << ((struct MetaStdLfs*)x.value)->refcount <<
108                       std::endl;
109             break;
110 
111         case STORE_META_URL:
112             assert (((char *)x.value)[x.length - 1] == 0);
113             std::cout << "URL: " << (char *)x.value << std::endl;
114             break;
115 
116         default:
117             std::cout << "Unknown store meta type: " << (int)x.getType() <<
118                       " of length " << x.length << std::endl;
119             break;
120         }
121     }
122 };
123 
124 int
main(int argc,char * argv[])125 main(int argc, char *argv[])
126 {
127     int fd = -1;
128     StoreMeta *metadata = NULL;
129 
130     try {
131         if (argc != 2)
132             throw std::runtime_error("No filename provided");
133 
134         fd = open (argv[1], O_RDONLY | O_BINARY);
135 
136         if (fd < 0)
137             throw std::runtime_error("Could not open file.");
138 
139         char tempbuf[SM_PAGE_SIZE];
140 
141         int len = read(fd, tempbuf, SM_PAGE_SIZE);
142 
143         if (len < 0)
144             throw std::runtime_error("Could not read header into memory.");
145 
146         close (fd);
147 
148         fd = -1;
149 
150         int hdr_len;
151 
152         StoreMetaUnpacker aBuilder(tempbuf, len, &hdr_len);
153 
154         metadata = aBuilder.createStoreMeta ();
155 
156         cache_key key[SQUID_MD5_DIGEST_LENGTH];
157 
158         memset(key, '\0', SQUID_MD5_DIGEST_LENGTH);
159 
160         DumpStoreMeta dumper;
161 
162         for_each(*metadata, dumper);
163 
164         return 0;
165     } catch (const std::exception &e) {
166         std::cout << "Failed : " << e.what() << std::endl;
167 
168         if (fd >= 0)
169             close(fd);
170 
171         if (metadata)
172             StoreMeta::FreeList(&metadata);
173 
174         return 1;
175     }
176 }
177 
178