2626#include < stdlib.h>
2727
2828#include " common/datapack.h"
29+ #include " common/server_connection.h"
2930#include " errors/saunafs_error_codes.h"
3031#include " errors/sfserr.h"
3132#include " tools/tools_commands.h"
@@ -40,122 +41,133 @@ static void get_trashtime_usage() {
4041}
4142
4243static int get_trashtime (const char *fname, uint8_t mode) {
43- uint32_t cmd, leng ;
44+ uint32_t msgid = 0 ;
4445 inode_t inode;
45- uint32_t fn, dn , i;
46+ uint32_t fileNodes, directoryNodes , i;
4647 uint32_t trashtime;
4748 uint32_t cnt;
48- int fd;
49- fd = open_master_conn (fname, &inode, nullptr , false );
50- if (fd < 0 ) {
51- return -1 ;
52- }
49+ uint8_t status;
5350
54- constexpr uint32_t kGetTrashTimePayloadSize = sizeof (uint32_t ) + sizeof (inode) + sizeof (mode);
55- constexpr uint32_t kReqBuffSize =
56- sizeof (cmd) + sizeof (kGetTrashTimePayloadSize ) + kGetTrashTimePayloadSize ;
57- uint8_t reqbuff[kReqBuffSize ], *wptr, *buff;
58- const uint8_t *rptr;
59-
60- wptr = reqbuff;
61- put32bit (&wptr, CLTOMA_FUSE_GETTRASHTIME);
62- put32bit (&wptr, kGetTrashTimePayloadSize );
63- put32bit (&wptr, 0 );
64- putINode (&wptr, inode);
65- put8bit (&wptr, mode);
66- if (tcpwrite (fd, reqbuff, kReqBuffSize ) != kReqBuffSize ) {
67- printf (" %s: master query: send error\n " , fname);
68- close_master_conn (1 );
69- return -1 ;
70- }
71- if (tcpread (fd, reqbuff, 8 ) != 8 ) {
72- printf (" %s: master query: receive error\n " , fname);
73- close_master_conn (1 );
74- return -1 ;
75- }
76- rptr = reqbuff;
77- get32bit (&rptr, cmd);
78- get32bit (&rptr, leng);
79- if (cmd != MATOCL_FUSE_GETTRASHTIME) {
80- printf (" %s: master query: wrong answer (type)\n " , fname);
81- close_master_conn (1 );
82- return -1 ;
83- }
84- buff = (uint8_t *)malloc (leng);
85- if (tcpread (fd, buff, leng) != (int32_t )leng) {
86- printf (" %s: master query: receive error\n " , fname);
87- free (buff);
88- close_master_conn (1 );
89- return -1 ;
90- }
91- close_master_conn (0 );
92- rptr = buff;
93- get32bit (&rptr, cmd); // queryid
94- if (cmd != 0 ) {
95- printf (" %s: master query: wrong answer (queryid)\n " , fname);
96- free (buff);
97- return -1 ;
98- }
99- leng -= 4 ;
100- if (leng == 1 ) {
101- printf (" %s: %s\n " , fname, saunafs_error_string (*rptr));
102- free (buff);
103- return -1 ;
104- } else if (leng < 8 || leng % 8 != 0 ) {
105- printf (" %s: master query: wrong answer (leng)\n " , fname);
106- free (buff);
107- return -1 ;
108- } else if (mode == GMODE_NORMAL && leng != 16 ) {
109- printf (" %s: master query: wrong answer (leng)\n " , fname);
110- free (buff);
111- return -1 ;
112- }
113- if (mode == GMODE_NORMAL) {
114- get32bit (&rptr, fn);
115- get32bit (&rptr, dn);
116- get32bit (&rptr, trashtime);
117- get32bit (&rptr, cnt);
118- if ((fn != 0 || dn != 1 ) && (fn != 1 || dn != 0 )) {
119- printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
120- free (buff);
51+ MessageBuffer request, response;
52+
53+ int fd = open_master_conn (fname, &inode, nullptr , false );
54+ if (fd < 0 ) { return -1 ; }
55+
56+ try {
57+ serializeLegacyPacket (request, CLTOMA_FUSE_GETTRASHTIME, msgid, inode, mode);
58+
59+ response = ServerConnection::sendAndReceive (fd, request, MATOCL_FUSE_GETTRASHTIME);
60+
61+ const uint8_t *rptr = response.data ();
62+
63+ get32bit (&rptr, msgid);
64+ if (msgid != 0 ) {
65+ printf (" %s: master query: wrong answer (queryid)\n " , fname);
66+ close_master_conn (1 );
12167 return -1 ;
12268 }
123- if (cnt != 1 ) {
124- printf (" %s: master query: wrong answer (cnt)\n " , fname);
125- free (buff);
69+
70+ uint32_t bodySize = static_cast <uint32_t >(response.size () - sizeof (msgid));
71+
72+ if (bodySize == sizeof (status)) {
73+ status = *rptr;
74+ printf (" %s: %s\n " , fname, saunafs_error_string (status));
75+ close_master_conn (0 );
76+ return (status == SAUNAFS_STATUS_OK) ? 0 : -1 ;
77+ }
78+
79+ const uint32_t headerFieldsSize = sizeof (fileNodes) + sizeof (directoryNodes);
80+
81+ if (bodySize < headerFieldsSize) {
82+ printf (" %s: master query: wrong answer (leng)\n " , fname);
83+ close_master_conn (1 );
84+ return -1 ;
85+ }
86+
87+ get32bit (&rptr, fileNodes);
88+ get32bit (&rptr, directoryNodes);
89+
90+ bodySize -= headerFieldsSize;
91+
92+ if (mode == GMODE_NORMAL) {
93+ const uint32_t expectedNormalBody = sizeof (trashtime) + sizeof (cnt);
94+ if (bodySize != expectedNormalBody) {
95+ printf (" %s: master query: wrong answer (leng)\n " , fname);
96+ close_master_conn (1 );
97+ return -1 ;
98+ }
99+
100+ get32bit (&rptr, trashtime);
101+ get32bit (&rptr, cnt);
102+
103+ if ((fileNodes != 0 || directoryNodes != 1 ) &&
104+ (fileNodes != 1 || directoryNodes != 0 )) {
105+ printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
106+ close_master_conn (1 );
107+ return -1 ;
108+ }
109+
110+ if (cnt != 1 ) {
111+ printf (" %s: master query: wrong answer (cnt)\n " , fname);
112+ close_master_conn (1 );
113+ return -1 ;
114+ }
115+
116+ close_master_conn (0 );
117+ printf (" %s: %" PRIu32 " \n " , fname, trashtime);
118+ return 0 ;
119+ }
120+
121+ const uint32_t entrySize = sizeof (trashtime) + sizeof (cnt);
122+ const uint32_t expectedAggregatedBody = (fileNodes + directoryNodes) * entrySize;
123+
124+ if (bodySize != expectedAggregatedBody) {
125+ printf (" %s: master query: wrong answer (leng)\n " , fname);
126+ close_master_conn (1 );
126127 return -1 ;
127128 }
128- printf (" %s: %" PRIu32 " \n " , fname, trashtime);
129- } else {
129+
130130 std::vector<std::pair<uint32_t , uint32_t >> files;
131131 std::vector<std::pair<uint32_t , uint32_t >> dirs;
132- get32bit (&rptr, fn);
133- get32bit (&rptr, dn );
134- files .reserve (fn );
135- dirs. reserve (dn);
136- for (i = 0 ; i < fn ; ++i) {
132+
133+ files. reserve (fileNodes );
134+ dirs .reserve (directoryNodes );
135+
136+ for (i = 0 ; i < fileNodes ; ++i) {
137137 get32bit (&rptr, trashtime);
138138 get32bit (&rptr, cnt);
139- files.push_back ({ trashtime, cnt} );
139+ files.emplace_back ( trashtime, cnt);
140140 }
141- for (i = 0 ; i < dn; ++i) {
141+
142+ for (i = 0 ; i < directoryNodes; ++i) {
142143 get32bit (&rptr, trashtime);
143144 get32bit (&rptr, cnt);
144- dirs.push_back ({ trashtime, cnt} );
145+ dirs.emplace_back ( trashtime, cnt);
145146 }
147+
148+ close_master_conn (0 );
149+
146150 std::sort (files.begin (), files.end ());
147151 std::sort (dirs.begin (), dirs.end ());
152+
148153 printf (" %s:\n " , fname);
154+
149155 for (const auto &entry : files) {
150156 printf (" files with trashtime %10" PRIu32 " :" , entry.first );
151157 print_number (" " , " \n " , entry.second , 1 , 0 , 1 );
152158 }
159+
153160 for (const auto &entry : dirs) {
154161 printf (" directories with trashtime %10" PRIu32 " :" , entry.first );
155162 print_number (" " , " \n " , entry.second , 1 , 0 , 1 );
156163 }
164+
165+ } catch (const Exception &e) {
166+ fprintf (stderr, " %s\n " , e.what ());
167+ close_master_conn (1 );
168+ return -1 ;
157169 }
158- free (buff);
170+
159171 return 0 ;
160172}
161173
0 commit comments