github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-fmt/syz-fmt.go (about)

     1  // Copyright 2017 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  // syz-fmt re-formats sys files into standard form.
     5  package main
     6  
     7  import (
     8  	"bytes"
     9  	"flag"
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  
    15  	"github.com/google/syzkaller/pkg/ast"
    16  	"github.com/google/syzkaller/pkg/osutil"
    17  	"github.com/google/syzkaller/pkg/tool"
    18  	"github.com/google/syzkaller/sys/targets"
    19  )
    20  
    21  var (
    22  	flagDryRun = flag.Bool("dry-run", false, "do not patch the files, just check if they are well formatted")
    23  )
    24  
    25  func main() {
    26  	defer tool.Init()()
    27  	args := flag.Args()
    28  	if len(args) < 1 {
    29  		fmt.Fprintf(os.Stderr, "usage: syz-fmt files... or dirs... or all\n")
    30  		os.Exit(1)
    31  	}
    32  	if len(args) == 1 && args[0] == "all" {
    33  		args = nil
    34  		for os := range targets.List {
    35  			args = append(args, filepath.Join("sys", os))
    36  		}
    37  	}
    38  	for _, arg := range args {
    39  		st, err := os.Stat(arg)
    40  		if err != nil {
    41  			fmt.Fprintf(os.Stderr, "failed to stat %v: %v\n", arg, err)
    42  			os.Exit(1)
    43  		}
    44  		if st.IsDir() {
    45  			files, err := os.ReadDir(arg)
    46  			if err != nil {
    47  				fmt.Fprintf(os.Stderr, "failed to read dir %v: %v\n", arg, err)
    48  				os.Exit(1)
    49  			}
    50  			for _, file := range files {
    51  				if !strings.HasSuffix(file.Name(), ".txt") {
    52  					continue
    53  				}
    54  				info, _ := file.Info()
    55  				processFile(filepath.Join(arg, file.Name()), info.Mode())
    56  			}
    57  		} else {
    58  			processFile(arg, st.Mode())
    59  		}
    60  	}
    61  }
    62  
    63  func processFile(file string, mode os.FileMode) {
    64  	data, err := os.ReadFile(file)
    65  	if err != nil {
    66  		fmt.Fprintf(os.Stderr, "failed to read file %v: %v\n", file, err)
    67  		os.Exit(1)
    68  	}
    69  	desc := ast.Parse(data, filepath.Base(file), nil)
    70  	if desc == nil {
    71  		os.Exit(1)
    72  	}
    73  	formatted := ast.Format(desc)
    74  	if bytes.Equal(data, formatted) {
    75  		return
    76  	}
    77  	if *flagDryRun {
    78  		fmt.Fprintf(os.Stderr, "%v is not well-formatted, please run syz-fmt against it\n", file)
    79  		os.Exit(2)
    80  		return
    81  	}
    82  	fmt.Printf("reformatting %v\n", file)
    83  	if err := osutil.Rename(file, file+"~"); err != nil {
    84  		fmt.Fprintf(os.Stderr, "%v\n", err)
    85  		os.Exit(1)
    86  	}
    87  	if err := os.WriteFile(file, formatted, mode); err != nil {
    88  		fmt.Fprintf(os.Stderr, "%v\n", err)
    89  		os.Exit(1)
    90  	}
    91  }