]> Cypherpunks.ru repositories - nncp.git/blob - src/cypherpunks.ru/nncp/humanizer.go
Remote command execution
[nncp.git] / src / cypherpunks.ru / nncp / humanizer.go
1 /*
2 NNCP -- Node to Node copy
3 Copyright (C) 2016-2018 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package nncp
20
21 import (
22         "fmt"
23         "regexp"
24         "strconv"
25         "strings"
26         "time"
27
28         "github.com/dustin/go-humanize"
29 )
30
31 func (ctx *Ctx) Humanize(s string) string {
32         s = strings.TrimRight(s, "\n")
33         splitted := strings.SplitN(s, " ", 4)
34         if len(splitted) != 4 {
35                 return s
36         }
37         var level string
38         if splitted[0] == "E" {
39                 level = "ERROR "
40         }
41         when, err := time.Parse(time.RFC3339Nano, splitted[1])
42         if err != nil {
43                 return s
44         }
45         who := splitted[2][1:]
46         closingBracket := strings.LastIndex(splitted[3], "]")
47         if closingBracket == -1 {
48                 return s
49         }
50         rem := strings.Trim(splitted[3][closingBracket+1:], " ")
51         sds := make(map[string]string)
52
53         re := regexp.MustCompile(`\w+="[^"]+"`)
54         for _, pair := range re.FindAllString(splitted[3][:closingBracket+1], -1) {
55                 sep := strings.Index(pair, "=")
56                 sds[pair[:sep]] = pair[sep+2 : len(pair)-1]
57         }
58
59         nodeS := sds["node"]
60         node, err := ctx.FindNode(nodeS)
61         if err == nil {
62                 nodeS = node.Name
63         }
64         var size string
65         if sizeRaw, exists := sds["size"]; exists {
66                 sp, err := strconv.ParseUint(sizeRaw, 10, 64)
67                 if err != nil {
68                         return s
69                 }
70                 size = humanize.IBytes(uint64(sp))
71         }
72
73         var msg string
74         switch who {
75         case "tx":
76                 switch sds["type"] {
77                 case "file":
78                         msg = fmt.Sprintf(
79                                 "File %s (%s) transfer to %s:%s: %s",
80                                 sds["src"], size, nodeS, sds["dst"], rem,
81                         )
82                 case "freq":
83                         msg = fmt.Sprintf(
84                                 "File request from %s:%s to %s: %s",
85                                 nodeS, sds["src"], sds["dst"], rem,
86                         )
87                 case "exec":
88                         msg = fmt.Sprintf(
89                                 "Exec to %s@%s (%s): %s",
90                                 nodeS, sds["dst"], size, rem,
91                         )
92                 case "trns":
93                         msg = fmt.Sprintf(
94                                 "Transitional packet to %s (%s) (nice %s): %s",
95                                 nodeS, size, sds["nice"], rem,
96                         )
97                 default:
98                         return s
99                 }
100                 if err, exists := sds["err"]; exists {
101                         msg += ": " + err
102                 }
103         case "rx":
104                 switch sds["type"] {
105                 case "exec":
106                         msg = fmt.Sprintf(
107                                 "Got exec from %s to %s (%s)",
108                                 nodeS, sds["dst"], size,
109                         )
110                 case "file":
111                         msg = fmt.Sprintf("Got file %s (%s) from %s", sds["dst"], size, nodeS)
112                 case "freq":
113                         msg = fmt.Sprintf("Got file request %s to %s", sds["src"], nodeS)
114                 case "trns":
115                         nodeT := sds["dst"]
116                         node, err := ctx.FindNode(nodeT)
117                         if err == nil {
118                                 nodeT = node.Name
119                         }
120                         msg = fmt.Sprintf(
121                                 "Got transitional packet from %s to %s (%s)",
122                                 nodeS, nodeT, size,
123                         )
124                 default:
125                         return s
126                 }
127                 if err, exists := sds["err"]; exists {
128                         msg += ": " + err
129                 }
130         case "check":
131                 msg = fmt.Sprintf("Checking: %s/%s/%s", sds["node"], sds["xx"], sds["pkt"])
132                 if err, exists := sds["err"]; exists {
133                         msg += fmt.Sprintf(" %s", err)
134                 }
135         case "nncp-xfer":
136                 switch sds["xx"] {
137                 case "rx":
138                         msg = "Packet transfer, received from"
139                 case "tx":
140                         msg = "Packet transfer, sent to"
141                 default:
142                         return s
143                 }
144                 if nodeS != "" {
145                         msg += " node " + nodeS
146                 }
147                 if size != "" {
148                         msg += fmt.Sprintf(" (%s)", size)
149                 }
150                 if err, exists := sds["err"]; exists {
151                         msg += ": " + err
152                 }
153         case "nncp-bundle":
154                 switch sds["xx"] {
155                 case "rx":
156                         msg = "Bundle transfer, received from"
157                 case "tx":
158                         msg = "Bundle transfer, sent to"
159                 default:
160                         return s
161                 }
162                 if nodeS != "" {
163                         msg += " node " + nodeS
164                 }
165                 msg += " " + sds["pkt"]
166                 if size != "" {
167                         msg += fmt.Sprintf(" (%s)", size)
168                 }
169                 if err, exists := sds["err"]; exists {
170                         msg += ": " + err
171                 }
172         case "nncp-rm":
173                 msg += "removing " + sds["file"]
174         case "call-start":
175                 msg = fmt.Sprintf("Connected to %s", nodeS)
176         case "call-finish":
177                 rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
178                 if err != nil {
179                         return s
180                 }
181                 rxs, err := strconv.ParseUint(sds["rxspeed"], 10, 64)
182                 if err != nil {
183                         return s
184                 }
185                 tx, err := strconv.ParseUint(sds["txbytes"], 10, 64)
186                 if err != nil {
187                         return s
188                 }
189                 txs, err := strconv.ParseUint(sds["txspeed"], 10, 64)
190                 if err != nil {
191                         return s
192                 }
193                 msg = fmt.Sprintf(
194                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
195                         nodeS,
196                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
197                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
198                 )
199         case "sp-infos":
200                 switch sds["xx"] {
201                 case "rx":
202                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
203                 case "tx":
204                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
205                 default:
206                         return s
207                 }
208                 msg += fmt.Sprintf("%s packets, %s", sds["pkts"], size)
209         case "sp-file":
210                 switch sds["xx"] {
211                 case "rx":
212                         msg = "Got packet "
213                 case "tx":
214                         msg = "Sent packet "
215                 default:
216                         return s
217                 }
218                 fullsize, err := strconv.ParseUint(sds["fullsize"], 10, 64)
219                 if err != nil {
220                         return s
221                 }
222                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
223                 if err != nil {
224                         return s
225                 }
226                 msg += fmt.Sprintf(
227                         "%s %d%% (%s / %s)",
228                         sds["hash"],
229                         100*sizeParsed/fullsize,
230                         humanize.IBytes(uint64(sizeParsed)),
231                         humanize.IBytes(uint64(fullsize)),
232                 )
233         case "sp-done":
234                 switch sds["xx"] {
235                 case "rx":
236                         msg = fmt.Sprintf("Packet %s is retreived (%s)", sds["hash"], size)
237                 case "tx":
238                         msg = fmt.Sprintf("Packet %s is sent", sds["hash"])
239                 default:
240                         return s
241                 }
242         case "nncp-reass":
243                 chunkNum, exists := sds["chunk"]
244                 if exists {
245                         msg = fmt.Sprintf(
246                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
247                                 sds["path"],
248                                 chunkNum,
249                                 rem,
250                         )
251                 } else {
252                         msg = fmt.Sprintf(
253                                 "Reassembling chunked file \"%s\": %s",
254                                 sds["path"],
255                                 rem,
256                         )
257                 }
258                 if err, exists := sds["err"]; exists {
259                         msg += ": " + err
260                 }
261         case "lockdir":
262                 msg = fmt.Sprintf("Acquire lock for %s: %s", sds["path"], sds["err"])
263         default:
264                 return s
265         }
266         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg)
267 }