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,142 @@ 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+ // ---- Status packet ----
69+ if (bodySize == szU8) {
70+ uint8_t 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+ // ---- Read fn / dn ----
77+ if (bodySize < 2 * szU8) {
78+ printf (" %s: master query: wrong answer (leng)\n " , fname);
79+ close_master_conn (1 );
12480 return -1 ;
12581 }
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 ;
82+
83+ uint8_t fn = get8bit (&rptr);
84+ uint8_t dn = get8bit (&rptr);
85+
86+ bodySize -= 2 * szU8;
87+
88+ // NORMAL MODE
89+ if (mode == GMODE_NORMAL) {
90+ const uint32_t expectedNormalBody = szU8 + szU32; // eattr + cnt
91+
92+ if (bodySize != expectedNormalBody) {
93+ printf (" %s: master query: wrong answer (leng)\n " , fname);
94+ close_master_conn (1 );
95+ return -1 ;
96+ }
97+
98+ uint8_t eattr = get8bit (&rptr);
99+ uint32_t cnt;
100+ get32bit (&rptr, cnt);
101+
102+ if ((fn != 0 || dn != 1 ) && (fn != 1 || dn != 0 )) {
103+ printf (" %s: master query: wrong answer (fn,dn)\n " , fname);
104+ close_master_conn (1 );
105+ return -1 ;
106+ }
107+
108+ if (cnt != 1 ) {
109+ printf (" %s: master query: wrong answer (cnt)\n " , fname);
110+ close_master_conn (1 );
111+ return -1 ;
112+ }
113+
114+ close_master_conn (0 );
115+
116+ printf (" %s: " , fname);
117+
118+ if (eattr == 0 ) {
119+ printf (" -\n " );
120+ return 0 ;
121+ }
122+
123+ bool first = true ;
124+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
125+ if (eattr & (1u << j)) {
126+ printf (" %s%s" , first ? " " : " ," , eattrtab[j]);
127+ first = false ;
133128 }
134129 }
135130 printf (" \n " );
136- } else {
137- printf ( " - \n " ) ;
131+
132+ return 0 ;
138133 }
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 ;
134+
135+ // AGGREGATED MODE
136+ const uint32_t entrySize = szU8 + szU32; // eattr + cnt
137+ const uint32_t expectedAggregatedBody = (fn + dn) * entrySize;
138+
139+ if (bodySize != expectedAggregatedBody) {
140+ printf (" %s: master query: wrong answer (leng)\n " , fname);
141+ close_master_conn (1 );
142+ return -1 ;
144143 }
145- fn = get8bit (&rptr);
146- dn = get8bit (&rptr);
147- for (i = 0 ; i < fn; i++) {
148- eattr = get8bit (&rptr);
144+
145+ uint32_t fcnt[EATTR_BITS] = {};
146+ uint32_t dcnt[EATTR_BITS] = {};
147+
148+ for (uint8_t i = 0 ; i < fn; ++i) {
149+ uint8_t eattr = get8bit (&rptr);
150+ uint32_t cnt;
149151 get32bit (&rptr, cnt);
150- for (j = 0 ; j < EATTR_BITS; j++) {
151- if (eattr & (1 << j)) {
152- fcnt[j] += cnt;
153- }
152+
153+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
154+ if (eattr & (1u << j)) { fcnt[j] += cnt; }
154155 }
155156 }
156- for (i = 0 ; i < dn; i++) {
157- eattr = get8bit (&rptr);
157+
158+ for (uint8_t i = 0 ; i < dn; ++i) {
159+ uint8_t eattr = get8bit (&rptr);
160+ uint32_t cnt;
158161 get32bit (&rptr, cnt);
159- for (j = 0 ; j < EATTR_BITS; j++) {
160- if (eattr & (1 << j)) {
161- dcnt[j] += cnt;
162- }
162+
163+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
164+ if (eattr & (1u << j)) { dcnt[j] += cnt; }
163165 }
164166 }
167+
168+ close_master_conn (0 );
169+
165170 printf (" %s:\n " , fname);
166- for (j = 0 ; j < EATTR_BITS; j++) {
171+
172+ for (uint8_t j = 0 ; j < EATTR_BITS; ++j) {
167173 if (eattrtab[j][0 ]) {
168174 printf (" not directory nodes with attribute %16s :" , eattrtab[j]);
169175 print_number (" " , " \n " , fcnt[j], 1 , 0 , 1 );
176+
170177 printf (" directories with attribute %16s :" , eattrtab[j]);
171178 print_number (" " , " \n " , dcnt[j], 1 , 0 , 1 );
172179 } else {
@@ -180,8 +187,13 @@ static int get_eattr(const char *fname, uint8_t mode) {
180187 }
181188 }
182189 }
190+
191+ } catch (Exception &e) {
192+ fprintf (stderr, " %s\n " , e.what ());
193+ close_master_conn (1 );
194+ return -1 ;
183195 }
184- free (buff);
196+
185197 return 0 ;
186198}
187199
0 commit comments