1 #include <string.h>
2 #include <stdio.h>
3 #include "afpfs-ng/map_def.h"
4 #include "afpfs-ng/dsi.h"
5 #include "afpfs-ng/afp.h"
6
afp_status_header(char * text,int * len)7 int afp_status_header(char * text, int * len)
8 {
9 int pos;
10 memset(text,0,*len);
11
12 pos=snprintf(text,*len,"AFPFS Version: %s\n"
13 "UAMs compiled in: %s\n",
14 AFPFS_VERSION,
15 get_uam_names_list());
16 *len-=pos;
17 if (*len==0) return -1;
18 return pos;
19 }
20
print_volume_status(struct afp_volume * v,char * text,int * pos_p,int * len)21 static void print_volume_status(struct afp_volume * v,
22 char * text,int * pos_p, int * len)
23 {
24 struct afp_server * s = v->server;
25 int pos = *pos_p;
26 unsigned int fl = v->extra_flags;
27
28 pos+=snprintf(text+pos,*len-pos,
29 " Volume %s, id %d, attribs 0x%x mounted: %s%s\n",
30 v->volume_name_printable,v->volid,
31 v->attributes,
32 (v->mounted==AFP_VOLUME_MOUNTED) ? v->mountpoint:"No",
33 ((v->mounted==AFP_VOLUME_MOUNTED) && (volume_is_readonly(v))) ?
34 " (read only)":"");
35
36 if (v->mounted==AFP_VOLUME_MOUNTED) {
37 pos+=snprintf(text+pos,*len-pos,
38 " did cache stats: %llu miss, %llu hit, %llu expired, %llu force removal\n uid/gid mapping: %s (%d/%d)\n",
39 v->did_cache_stats.misses, v->did_cache_stats.hits,
40 v->did_cache_stats.expired,
41 v->did_cache_stats.force_removed,
42 get_mapping_name(v),
43 s->server_uid,s->server_gid);
44 pos+=snprintf(text+pos,*len-pos,
45 " Unix permissions: %s",
46 (v->extra_flags&VOLUME_EXTRA_FLAGS_VOL_SUPPORTS_UNIX)?
47 "Yes":"No");
48
49 if (s->server_type==AFPFS_SERVER_TYPE_NETATALK) {
50 pos+=snprintf(text+pos,*len-pos,
51 ", Netatalk permissions broken: ");
52
53 if (fl&VOLUME_EXTRA_FLAGS_VOL_CHMOD_KNOWN)
54 if (fl&VOLUME_EXTRA_FLAGS_VOL_CHMOD_BROKEN)
55 pos+=snprintf(text+pos,*len-pos,
56 "Yes\n");
57 else
58 pos+=snprintf(text+pos,*len-pos,
59 "No\n");
60 else
61 pos+=snprintf(text+pos,*len-pos,
62 "Unknown\n");
63 }
64 }
65 *pos_p=pos;
66 }
67
afp_status_server(struct afp_server * s,char * text,int * len)68 int afp_status_server(struct afp_server * s, char * text, int * len)
69 {
70 int j;
71 struct afp_volume *v;
72 char signature_string[AFP_SIGNATURE_LEN*2+1];
73 int pos=0;
74 int firsttime=0;
75 struct dsi_request * request;
76
77 memset(text,0,*len);
78
79 if (s==NULL) {
80 pos+=snprintf(text+pos,*len-pos,
81 "Not connected to any servers\n");
82 goto out;
83 }
84
85 for (j=0;j<AFP_SIGNATURE_LEN;j++)
86 sprintf(signature_string+(j*2),"%02x",
87 (unsigned int) ((char) s->signature[j]));
88
89 pos+=snprintf(text+pos,*len-pos,
90 "Server %s\n"
91 " connection: %s:%d %s\n"
92 " using AFP version: %s\n",
93 s->server_name_printable,
94 inet_ntoa(s->address.sin_addr),ntohs(s->address.sin_port),
95 (s->connect_state==SERVER_STATE_DISCONNECTED ?
96 "Disconnected" : "(active)"),
97 s->using_version->av_name
98 );
99
100 pos+=snprintf(text+pos,*len-pos,
101 " server UAMs: ");
102
103 for (j=1;j<0x100;j<<=1) {
104 if (j & s->supported_uams) {
105 if (firsttime!=0)
106 pos+=snprintf(text+pos,*len-pos,
107 ", ");
108 if (j==s->using_uam)
109 pos+=snprintf(text+pos,*len-pos,
110 "%s (used)",
111 uam_bitmap_to_string(j));
112 else
113 pos+=snprintf(text+pos,*len-pos,
114 "%s",
115 uam_bitmap_to_string(j));
116 firsttime=1;
117 }
118 };
119
120 pos+=snprintf(text+pos,*len-pos,
121 "\n login message: %s\n"
122 " type: %s",
123 s->loginmesg, s->machine_type);
124
125
126 pos+=snprintf(text+pos,*len-pos,
127 "\n"
128 " signature: %s\n"
129 " transmit delay: %ums\n"
130 " quantums: %u(tx) %u(rx)\n"
131 " last request id: %d in queue: %llu\n",
132 signature_string,
133 s->tx_delay,
134 s->tx_quantum, s->rx_quantum,
135 s->lastrequestid,s->stats.requests_pending);
136
137 for (request=s->command_requests;request;request=request->next) {
138 pos+=snprintf(text+pos,*len-pos,
139 " request %d, %s\n",
140 request->requestid, afp_get_command_name(request->subcommand));
141 }
142
143 pos+=snprintf(text+pos,*len-pos,
144 " transfer: %llu(rx) %llu(tx)\n"
145 " runt packets: %llu\n",
146 s->stats.rx_bytes,s->stats.tx_bytes,
147 s->stats.runt_packets);
148
149 if (*len==0) goto out;
150
151 for (j=0;j<s->num_volumes;j++) {
152 v=&s->volumes[j];
153 print_volume_status(v,text,&pos,len);
154 pos+=snprintf(text+pos,*len-pos,"\n");
155 }
156
157 out:
158 *len-=pos;
159 return pos;
160
161 }
162