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  }