]> Cypherpunks.ru repositories - nncp.git/blob - src/cypherpunks.ru/nncp/tmp.go
3d73333a2ed764c9dd1ba38f03767cbc4d6428d5
[nncp.git] / src / cypherpunks.ru / nncp / tmp.go
1 /*
2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2019 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         "bufio"
23         "hash"
24         "io"
25         "io/ioutil"
26         "os"
27         "path/filepath"
28
29         "golang.org/x/crypto/blake2b"
30 )
31
32 func (ctx *Ctx) NewTmpFile() (*os.File, error) {
33         jobsPath := filepath.Join(ctx.Spool, "tmp")
34         var err error
35         if err = os.MkdirAll(jobsPath, os.FileMode(0700)); err != nil {
36                 return nil, err
37         }
38         fd, err := ioutil.TempFile(jobsPath, "")
39         if err == nil {
40                 ctx.LogD("tmp", SDS{"src": fd.Name()}, "created")
41         }
42         return fd, err
43 }
44
45 type TmpFileWHash struct {
46         W   *bufio.Writer
47         Fd  *os.File
48         Hsh hash.Hash
49         ctx *Ctx
50 }
51
52 func (ctx *Ctx) NewTmpFileWHash() (*TmpFileWHash, error) {
53         tmp, err := ctx.NewTmpFile()
54         if err != nil {
55                 return nil, err
56         }
57         hsh, err := blake2b.New256(nil)
58         if err != nil {
59                 return nil, err
60         }
61         return &TmpFileWHash{
62                 W:   bufio.NewWriter(io.MultiWriter(hsh, tmp)),
63                 Fd:  tmp,
64                 Hsh: hsh,
65                 ctx: ctx,
66         }, nil
67 }
68
69 func (tmp *TmpFileWHash) Cancel() {
70         tmp.Fd.Truncate(0)
71         tmp.Fd.Close()
72         os.Remove(tmp.Fd.Name())
73 }
74
75 func (tmp *TmpFileWHash) Commit(dir string) error {
76         var err error
77         if err = os.MkdirAll(dir, os.FileMode(0700)); err != nil {
78                 return err
79         }
80         if err = tmp.W.Flush(); err != nil {
81                 tmp.Fd.Close()
82                 return err
83         }
84         if err = tmp.Fd.Sync(); err != nil {
85                 tmp.Fd.Close()
86                 return err
87         }
88         tmp.Fd.Close()
89         checksum := ToBase32(tmp.Hsh.Sum(nil))
90         tmp.ctx.LogD("tmp", SDS{"src": tmp.Fd.Name(), "dst": checksum}, "commit")
91         return os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum))
92 }