golang.org/x/build@v0.0.0-20240506185731-218518f32b70/env/windows-arm64/azure/writefilegenpowerscript.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Command writefilegenpowerscript reads an ASCII input file and a 6 // target windows path, and writes out a Windows PowerShell script 7 // that will write the content of the file to the specified location. 8 // Notes: 9 // - this program is limited to writing text files; trying 10 // to write a binary would most likely not end well. 11 // - it is assumed that we want linux-style ("\n") and not 12 // windows-style ("\r\n") line endings 13 14 package main 15 16 import ( 17 "flag" 18 "fmt" 19 "log" 20 "os" 21 "strings" 22 ) 23 24 var ( 25 infileflag = flag.String("input-file", "", "Path to the input file") 26 tgtpathflag = flag.String("windows-target-path", "", "Target full pathname to write on Windows") 27 outfileflag = flag.String("output-file", "", "Name of script to write") 28 ownerflag = flag.String("set-owner", "", "Username to assign as owner of windows file (optional)") 29 denyflag = flag.String("deny-user-read", "", "Username to which we'll deny read permission on windows file after creation (optional)") 30 ) 31 32 func main() { 33 flag.Usage = func() { 34 fmt.Fprintln(os.Stderr, "Usage: writefilegenpowerscript -input-file AAA -output-file BBB -windows-target-path C:\\CCC") 35 flag.PrintDefaults() 36 } 37 flag.Parse() 38 if *infileflag == "" || *outfileflag == "" || *tgtpathflag == "" { 39 flag.Usage() 40 os.Exit(2) 41 } 42 // vet the windows path 43 if !strings.HasPrefix(*tgtpathflag, "C:\\") { 44 fmt.Fprintf(os.Stderr, "warning: suspicious windows target path %q, does not start with C drive prefix\n", *tgtpathflag) 45 } 46 47 // Slurp in the input file. 48 var lines []string 49 if content, err := os.ReadFile(*infileflag); err != nil { 50 log.Fatalf("reading %s: error %v", *infileflag, err) 51 } else { 52 lines = strings.Split(string(content), "\n") 53 } 54 55 // Open output file 56 of, err := os.OpenFile(*outfileflag, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 57 if err != nil { 58 log.Fatalf("opening %s for write: error %v", *outfileflag, err) 59 } 60 61 // Write content. 62 fmt.Fprintf(of, "Set-StrictMode -Version Latest\n") 63 fmt.Fprintf(of, "$path = \"%s\"\n", *tgtpathflag) 64 line0 := lines[0] 65 fmt.Fprintf(of, "$line0 = \"%s\"\n", line0) 66 fmt.Fprintf(of, "$line0 | Out-File -Encoding ascii $path\n") 67 for i := 1; i < len(lines)-1; i++ { 68 line := lines[i] 69 fmt.Fprintf(of, "Add-Content -Encoding ascii -Path $path -Value \"%s\"\n", line) 70 } 71 72 // The file we wrote has windows-style line endings; emit a 73 // separate step to convert back to linux-style. 74 fmt.Fprintf(of, "((Get-Content $path) -join \"`n\") + \"`n\" | Set-Content -NoNewline $path\n") 75 76 // Honor the -set-owner and/or -deny-user-read flag if set. 77 if *ownerflag != "" { 78 fmt.Fprintf(of, "icacls $path /setowner %s\n", *ownerflag) 79 } 80 if *denyflag != "" { 81 fmt.Fprintf(of, "icacls $path /deny %s:r\n", *denyflag) 82 } 83 84 // We're done. 85 if err := of.Close(); err != nil { 86 log.Fatalf("closing %s: error %v", *outfileflag, err) 87 } 88 }