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,140 @@ 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];
45- uint8_t eattr;
46- uint32_t cnt;
47- int fd;
48- fd = open_master_conn (fname, &inode, nullptr , false );
49- if (fd < 0 ) {
50- return -1 ;
51- }
5243
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);
44+ MessageBuffer request, response;
45+
46+ int fd = open_master_conn (fname, &inode, nullptr , false );
47+ if (fd < 0 ) { return -1 ; }
48+
49+ try {
50+ serializeLegacyPacket (request, CLTOMA_FUSE_GETEATTR, msgid, inode, mode);
51+
52+ response = ServerConnection::sendAndReceive (fd, request, MATOCL_FUSE_GETEATTR);
53+
54+ const uint8_t *rptr = response.data ();
55+
56+ get32bit (&rptr, msgid);
57+ if (msgid != 0 ) {
58+ printf (" %s: master query: wrong answer (queryid)\n " , fname);
59+ close_master_conn (1 );
11960 return -1 ;
12061 }
121- if (cnt != 1 ) {
122- printf (" %s: master query: wrong answer (cnt)\n " , fname);
123- free (buff);
62+
63+ const uint32_t szU8 = sizeof (uint8_t );
64+ const uint32_t szU32 = sizeof (uint32_t );
65+
66+ uint32_t bodySize = static_cast <uint32_t >(response.size () - sizeof (msgid));
67+
68+ if (bodySize == szU8) {
69+ uint8_t status = *rptr;
70+ printf (" %s: %s\n " , fname, saunafs_error_string (status));
71+ close_master_conn (0 );
72+ return (status == SAUNAFS_STATUS_OK) ? 0 : -1 ;
73+ }
74+
75+ if (bodySize < 2 * szU8) {
76+ printf (" %s: master query: wrong answer (leng)\n " , fname);
77+ close_master_conn (1 );
12478 return -1 ;
12579 }
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 ;
80+
81+ uint8_t fn = get8bit (&rptr);
82+ uint8_t dn = get8bit (&rptr);
83+
84+ bodySize -= 2 * szU8;
85+
86+ // NORMAL MODE
87+ if (mode == GMODE_NORMAL) {
88+ const uint32_t expectedNormalBody = szU8 + szU32; // eattr + cnt
89+
90+ if (bodySize != expectedNormalBody) {
91+ printf (" %s: master query: wrong answer (leng)\n " , fname);
92+ close_master_conn (1 );
93+ return -1 ;
94+ }
95+
96+ uint8_t eattr = get8bit (&rptr);
97+ uint32_t cnt;
98+ get32bit (&rptr, cnt);
99+
100+ if ((fn != 0 || dn != 1 ) && (fn != 1 || dn != 0 )) {
101+ printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
102+ close_master_conn (1 );
103+ return -1 ;
104+ }
105+
106+ if (cnt != 1 ) {
107+ printf (" %s: master query: wrong answer (cnt)\n " , fname);
108+ close_master_conn (1 );
109+ return -1 ;
110+ }
111+
112+ close_master_conn (0 );
113+
114+ printf (" %s: " , fname);
115+
116+ if (eattr == 0 ) {
117+ printf (" -\n " );
118+ return 0 ;
119+ }
120+
121+ bool first = true ;
122+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
123+ if (eattr & (1u << j)) {
124+ printf (" %s%s" , first ? " " : " ," , eattrtab[j]);
125+ first = false ;
133126 }
134127 }
135128 printf (" \n " );
136- } else {
137- printf ( " - \n " ) ;
129+
130+ return 0 ;
138131 }
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 ;
132+
133+ // AGGREGATED MODE
134+ const uint32_t entrySize = szU8 + szU32; // eattr + cnt
135+ const uint32_t expectedAggregatedBody = (fn + dn) * entrySize;
136+
137+ if (bodySize != expectedAggregatedBody) {
138+ printf (" %s: master query: wrong answer (leng)\n " , fname);
139+ close_master_conn (1 );
140+ return -1 ;
144141 }
145- fn = get8bit (&rptr);
146- dn = get8bit (&rptr);
147- for (i = 0 ; i < fn; i++) {
148- eattr = get8bit (&rptr);
142+
143+ uint32_t fcnt[EATTR_BITS] = {};
144+ uint32_t dcnt[EATTR_BITS] = {};
145+
146+ for (uint8_t i = 0 ; i < fn; ++i) {
147+ uint8_t eattr = get8bit (&rptr);
148+ uint32_t cnt;
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++) {
157- eattr = get8bit (&rptr);
155+
156+ for (uint8_t i = 0 ; i < dn; ++i) {
157+ uint8_t eattr = get8bit (&rptr);
158+ uint32_t cnt;
158159 get32bit (&rptr, cnt);
159- for (j = 0 ; j < EATTR_BITS; j++) {
160- if (eattr & (1 << j)) {
161- dcnt[j] += cnt;
162- }
160+
161+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
162+ if (eattr & (1u << j)) { dcnt[j] += cnt; }
163163 }
164164 }
165+
166+ close_master_conn (0 );
167+
165168 printf (" %s:\n " , fname);
166- for (j = 0 ; j < EATTR_BITS; j++) {
169+
170+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
167171 if (eattrtab[j][0 ]) {
168172 printf (" not directory nodes with attribute %16s :" , eattrtab[j]);
169173 print_number (" " , " \n " , fcnt[j], 1 , 0 , 1 );
174+
170175 printf (" directories with attribute %16s :" , eattrtab[j]);
171176 print_number (" " , " \n " , dcnt[j], 1 , 0 , 1 );
172177 } else {
@@ -180,8 +185,13 @@ static int get_eattr(const char *fname, uint8_t mode) {
180185 }
181186 }
182187 }
188+
189+ } catch (Exception &e) {
190+ fprintf (stderr, " %s\n " , e.what ());
191+ close_master_conn (1 );
192+ return -1 ;
183193 }
184- free (buff);
194+
185195 return 0 ;
186196}
187197
0 commit comments