2525#include < cstdint>
2626
2727#include " common/datapack.h"
28+ #include " common/server_connection.h"
2829#include " errors/saunafs_error_codes.h"
2930#include " errors/sfserr.h"
3031#include " tools/tools_commands.h"
@@ -37,136 +38,139 @@ static void get_eattr_usage() {
3738}
3839
3940static int get_eattr (const char *fname, uint8_t mode) {
40- uint32_t cmd, leng ;
41+ uint32_t msgid{ 0 } ;
4142 inode_t inode;
42- uint8_t fn, dn, i, j;
43- uint32_t fcnt[EATTR_BITS];
44- uint32_t dcnt[EATTR_BITS];
4543 uint8_t eattr;
4644 uint32_t cnt;
47- int fd;
48- fd = open_master_conn (fname, &inode, nullptr , false );
49- if (fd < 0 ) {
50- return -1 ;
51- }
45+ uint8_t status;
46+ uint8_t fileNodes, directoryNodes;
5247
53- constexpr uint32_t kGetEAttrPayload = sizeof (uint32_t ) + sizeof (inode) + sizeof (mode);
54- constexpr uint32_t kReqBuffSize = sizeof (cmd) + sizeof (kGetEAttrPayload ) + kGetEAttrPayload ;
55- uint8_t reqbuff[kReqBuffSize ], *wptr, *buff;
56- const uint8_t *rptr;
57-
58- wptr = reqbuff;
59- put32bit (&wptr, CLTOMA_FUSE_GETEATTR);
60- put32bit (&wptr, kGetEAttrPayload );
61- put32bit (&wptr, 0 );
62- putINode (&wptr, inode);
63- put8bit (&wptr, mode);
64- if (tcpwrite (fd, reqbuff, kReqBuffSize ) != kReqBuffSize ) {
65- printf (" %s: master query: send error\n " , fname);
66- close_master_conn (1 );
67- return -1 ;
68- }
69- if (tcpread (fd, reqbuff, 8 ) != 8 ) {
70- printf (" %s: master query: receive error\n " , fname);
71- close_master_conn (1 );
72- return -1 ;
73- }
74- rptr = reqbuff;
75- get32bit (&rptr, cmd);
76- get32bit (&rptr, leng);
77- if (cmd != MATOCL_FUSE_GETEATTR) {
78- printf (" %s: master query: wrong answer (type)\n " , fname);
79- close_master_conn (1 );
80- return -1 ;
81- }
82- buff = (uint8_t *)malloc (leng);
83- if (tcpread (fd, buff, leng) != (int32_t )leng) {
84- printf (" %s: master query: receive error\n " , fname);
85- free (buff);
86- close_master_conn (1 );
87- return -1 ;
88- }
89- close_master_conn (0 );
90- rptr = buff;
91- get32bit (&rptr, cmd); // queryid
92- if (cmd != 0 ) {
93- printf (" %s: master query: wrong answer (queryid)\n " , fname);
94- free (buff);
95- return -1 ;
96- }
97- leng -= 4 ;
98- if (leng == 1 ) {
99- printf (" %s: %s\n " , fname, saunafs_error_string (*rptr));
100- free (buff);
101- return -1 ;
102- } else if (leng % 5 != 2 ) {
103- printf (" %s: master query: wrong answer (leng)\n " , fname);
104- free (buff);
105- return -1 ;
106- } else if (mode == GMODE_NORMAL && leng != 7 ) {
107- printf (" %s: master query: wrong answer (leng)\n " , fname);
108- free (buff);
109- return -1 ;
110- }
111- if (mode == GMODE_NORMAL) {
112- fn = get8bit (&rptr);
113- dn = get8bit (&rptr);
114- eattr = get8bit (&rptr);
115- get32bit (&rptr, cnt);
116- if ((fn != 0 || dn != 1 ) && (fn != 1 || dn != 0 )) {
117- printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
118- free (buff);
48+ MessageBuffer request, response;
49+
50+ int fd = open_master_conn (fname, &inode, nullptr , false );
51+ if (fd < 0 ) { return -1 ; }
52+
53+ try {
54+ serializeLegacyPacket (request, CLTOMA_FUSE_GETEATTR, msgid, inode, mode);
55+
56+ response = ServerConnection::sendAndReceive (fd, request, MATOCL_FUSE_GETEATTR);
57+
58+ const uint8_t *rptr = response.data ();
59+
60+ get32bit (&rptr, msgid);
61+ if (msgid != 0 ) {
62+ printf (" %s: master query: wrong answer (queryid)\n " , fname);
63+ close_master_conn (1 );
11964 return -1 ;
12065 }
121- if (cnt != 1 ) {
122- printf (" %s: master query: wrong answer (cnt)\n " , fname);
123- free (buff);
66+
67+ uint32_t bodySize = static_cast <uint32_t >(response.size () - sizeof (msgid));
68+
69+ if (bodySize == sizeof (status)) {
70+ status = *rptr;
71+ printf (" %s: %s\n " , fname, saunafs_error_string (status));
72+ close_master_conn (0 );
73+ return (status == SAUNAFS_STATUS_OK) ? 0 : -1 ;
74+ }
75+
76+ if (bodySize < sizeof (fileNodes) + sizeof (directoryNodes)) {
77+ printf (" %s: master query: wrong answer (leng)\n " , fname);
78+ close_master_conn (1 );
12479 return -1 ;
12580 }
126- printf (" %s: " , fname);
127- if (eattr > 0 ) {
128- cnt = 0 ;
129- for (j = 0 ; j < EATTR_BITS; j++) {
130- if (eattr & (1 << j)) {
131- printf (" %s%s" , (cnt) ? " ," : " " , eattrtab[j]);
132- cnt = 1 ;
81+
82+ fileNodes = get8bit (&rptr);
83+ directoryNodes = get8bit (&rptr);
84+
85+ bodySize -= (sizeof (fileNodes) + sizeof (directoryNodes));
86+
87+ // NORMAL MODE
88+ if (mode == GMODE_NORMAL) {
89+ const uint32_t expectedNormalBody = sizeof (eattr) + sizeof (cnt);
90+
91+ if (bodySize != expectedNormalBody) {
92+ printf (" %s: master query: wrong answer (leng)\n " , fname);
93+ close_master_conn (1 );
94+ return -1 ;
95+ }
96+
97+ eattr = get8bit (&rptr);
98+ get32bit (&rptr, cnt);
99+
100+ if ((fileNodes != 0 || directoryNodes != 1 ) &&
101+ (fileNodes != 1 || directoryNodes != 0 )) {
102+ printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
103+ close_master_conn (1 );
104+ return -1 ;
105+ }
106+
107+ if (cnt != 1 ) {
108+ printf (" %s: master query: wrong answer (cnt)\n " , fname);
109+ close_master_conn (1 );
110+ return -1 ;
111+ }
112+
113+ close_master_conn (0 );
114+
115+ printf (" %s: " , fname);
116+
117+ if (eattr == 0 ) {
118+ printf (" -\n " );
119+ return 0 ;
120+ }
121+
122+ bool first = true ;
123+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
124+ if (eattr & (1u << j)) {
125+ printf (" %s%s" , first ? " " : " ," , eattrtab[j]);
126+ first = false ;
133127 }
134128 }
135129 printf (" \n " );
136- } else {
137- printf ( " - \n " ) ;
130+
131+ return 0 ;
138132 }
139- // printf("%s: %" PRIX8 "\n",fname,eattr);
140- } else {
141- for (j = 0 ; j < EATTR_BITS; j++) {
142- fcnt[j] = 0 ;
143- dcnt[j] = 0 ;
133+
134+ // AGGREGATED MODE
135+ const uint32_t entrySize = sizeof (eattr) + sizeof (cnt);
136+ const uint32_t expectedAggregatedBody = (fileNodes + directoryNodes) * entrySize;
137+
138+ if (bodySize != expectedAggregatedBody) {
139+ printf (" %s: master query: wrong answer (leng)\n " , fname);
140+ close_master_conn (1 );
141+ return -1 ;
144142 }
145- fn = get8bit (&rptr);
146- dn = get8bit (&rptr);
147- for (i = 0 ; i < fn; i++) {
143+
144+ uint32_t fcnt[EATTR_BITS] = {};
145+ uint32_t dcnt[EATTR_BITS] = {};
146+
147+ for (uint8_t i = 0 ; i < fileNodes; ++i) {
148148 eattr = get8bit (&rptr);
149149 get32bit (&rptr, cnt);
150- for (j = 0 ; j < EATTR_BITS; j++) {
151- if (eattr & (1 << j)) {
152- fcnt[j] += cnt;
153- }
150+
151+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
152+ if (eattr & (1u << j)) { fcnt[j] += cnt; }
154153 }
155154 }
156- for (i = 0 ; i < dn; i++) {
155+
156+ for (uint8_t i = 0 ; i < directoryNodes; ++i) {
157157 eattr = get8bit (&rptr);
158158 get32bit (&rptr, cnt);
159- for (j = 0 ; j < EATTR_BITS; j++) {
160- if (eattr & (1 << j)) {
161- dcnt[j] += cnt;
162- }
159+
160+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
161+ if (eattr & (1u << j)) { dcnt[j] += cnt; }
163162 }
164163 }
164+
165+ close_master_conn (0 );
166+
165167 printf (" %s:\n " , fname);
166- for (j = 0 ; j < EATTR_BITS; j++) {
168+
169+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
167170 if (eattrtab[j][0 ]) {
168171 printf (" not directory nodes with attribute %16s :" , eattrtab[j]);
169172 print_number (" " , " \n " , fcnt[j], 1 , 0 , 1 );
173+
170174 printf (" directories with attribute %16s :" , eattrtab[j]);
171175 print_number (" " , " \n " , dcnt[j], 1 , 0 , 1 );
172176 } else {
@@ -180,8 +184,13 @@ static int get_eattr(const char *fname, uint8_t mode) {
180184 }
181185 }
182186 }
187+
188+ } catch (const Exception &e) {
189+ fprintf (stderr, " %s\n " , e.what ());
190+ close_master_conn (1 );
191+ return -1 ;
183192 }
184- free (buff);
193+
185194 return 0 ;
186195}
187196
0 commit comments