1 package main 2 3 import ( 4 "archive/zip" 5 "io" 6 "os" 7 "path" 8 "strconv" 9 "sync" 10 ) 11 12 var pathFind sync.Mutex 13 14 func freePath(p string) string { 15 pathFind.Lock() 16 defer pathFind.Unlock() 17 for num := 0; num < 10000; num++ { 18 dir := path.Join(p, strconv.Itoa(num)) 19 _, err := os.Stat(dir) 20 if os.IsNotExist(err) { 21 os.MkdirAll(dir, 0755) 22 return dir 23 } 24 } 25 return "" 26 } 27 28 func archive(w io.Writer, p string) { 29 p = path.Clean(p) 30 zw := zip.NewWriter(w) 31 defer zw.Close() 32 paths := []string{p} 33 for len(paths) > 0 { 34 p := paths[0] 35 paths = paths[1:] 36 d, err := os.Open(p) 37 if err != nil { 38 continue 39 } 40 for { 41 fs, err := d.Readdir(1) 42 if err != nil { 43 break 44 } 45 fname := path.Join(p, fs[0].Name()) 46 if fs[0].IsDir() { 47 paths = append(paths, fname) 48 continue 49 } 50 if fs[0].Mode()&os.ModeSymlink > 0 { 51 continue 52 } 53 fh, _ := zip.FileInfoHeader(fs[0]) 54 fh.Name = fname[len(p)+1:] 55 fw, err := zw.CreateHeader(fh) 56 if err != nil { 57 return 58 } 59 f, err := os.Open(fname) 60 if err != nil { 61 continue 62 } 63 _, err = io.Copy(fw, f) 64 f.Close() 65 if err != nil { 66 return 67 } 68 } 69 } 70 }