/*
paster -- paste service
-Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2021-2022 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
"bytes"
"crypto/rand"
"crypto/sha512"
+ _ "embed"
"encoding/base32"
"encoding/hex"
"flag"
"fmt"
+ "html/template"
"io"
"os"
"strconv"
- "time"
+)
+
+var (
+ //go:embed asciicast.tmpl
+ ASCIICastHTMLTmplRaw string
+ ASCIICastHTMLTmpl = template.Must(template.New("asciicast").Parse(
+ ASCIICastHTMLTmplRaw,
+ ))
)
func fatal(s string) {
os.Exit(1)
}
+func asciicastHTML(playerPath, cast string) error {
+ var buf bytes.Buffer
+ err := ASCIICastHTMLTmpl.Execute(&buf, struct {
+ PlayerPath string
+ Cast string
+ }{
+ PlayerPath: playerPath,
+ Cast: cast,
+ })
+ if err != nil {
+ return err
+ }
+ fn := cast + ".html"
+ fd, err := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
+ if err != nil {
+ return err
+ }
+ if _, err = fd.Write(buf.Bytes()); err != nil {
+ os.Remove(fn)
+ return err
+ }
+ return fd.Close()
+}
+
func main() {
- maxSecs := flag.Uint("max-secs", 60, "Maximal time of aliveness (0=disable)")
maxSize := flag.Uint64("max-size", 1<<20, "Maximal upload size")
+ asciicastPath := flag.String("asciicast-path", "", "Generate HTMLs for .cast asciicasts, specify \"asciinema-player-v2.6.1\"")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: paster [options] URL [...]\n")
flag.PrintDefaults()
flag.Usage()
os.Exit(1)
}
- if *maxSecs > 0 {
- go func() {
- time.Sleep(time.Duration(*maxSecs) * time.Second)
- fatal("max aliveness time is reached")
- }()
- }
+ var fn string
r := bufio.NewReader(os.Stdin)
b, err := r.ReadByte()
if err != nil {
if _, err = io.ReadFull(rand.Reader, rnd); err != nil {
fatal(err.Error())
}
- fn := "." + base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(rnd) +
- ext
+ fn = "." + base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(rnd) + ext
fd, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
if err != nil {
fatal(err.Error())
if _, err = io.CopyN(mw, mr, int64(size-1)); err != nil {
goto Failed
}
- if _, err = mr.Read(buf[:1]); err != nil {
+ if len(buf) == 0 {
+ buf = append(buf, 0)
+ } else {
+ buf = buf[:1]
+ }
+ if _, err = mr.Read(buf); err != nil {
goto Failed
}
- if _, err = mw.Write(buf[:1]); err != nil {
+ if _, err = mw.Write(buf); err != nil {
goto Failed
}
if (ext == ".txt" || ext == ".url") && buf[0] != '\n' {
goto Failed
}
}
- if _, err = mr.Read(buf[:1]); err != nil {
+ if _, err = mr.Read(buf); err != nil {
goto Failed
}
if buf[0] != 'e' {
for _, u := range flag.Args() {
fmt.Println(u + fn[1:])
}
- fmt.Println(hex.EncodeToString(h.Sum(nil)[:512/2/8]))
+ fmt.Println("SHA512/2:", hex.EncodeToString(h.Sum(nil)[:512/2/8]))
+ if ext == ".cast" && *asciicastPath != "" {
+ if err = asciicastHTML(*asciicastPath, fn[1:]); err != nil {
+ goto Failed
+ }
+ for _, u := range flag.Args() {
+ fmt.Println(u + fn[1:] + ".html")
+ }
+ }
fmt.Fprintf(
os.Stderr,
"[%s]:%s %s %d\n",