package main import ( "bytes" "fmt" "io" "os" ) const flagStart = `-----{% start %}-----` const flagEnd = `-----{% end %}-----` func Self() string { exe, err := os.Executable() if err != nil { panic(err) } return exe } func main() { self := Self() selfFile, err := os.Open(self) if err != nil { panic("open self failed " + err.Error()) } defer selfFile.Close() newOffset, err := selfFile.Seek(-int64(len(flagEnd)), 2) if err != nil { panic("seek self failed " + err.Error()) } buf, err := io.ReadAll(selfFile) if err != nil { panic("read self end failed " + err.Error()) } alreadyAppendData := string(buf) == flagEnd endAt := newOffset + int64(len(flagEnd)) var embedData []byte if alreadyAppendData { // search start flag _, err = selfFile.Seek(0, 0) if err != nil { panic("seek self to start failed " + err.Error()) } readStartAt, err := searchInReader(selfFile, []byte(flagStart)) if err != nil { panic("search start flag failed " + err.Error()) } _, err = selfFile.Seek(int64(readStartAt), 0) if err != nil { panic("seek self to start flag failed " + err.Error()) } allData, err := io.ReadAll(selfFile) if err != nil { panic("read from start flag to end failed " + err.Error()) } embedData = allData[:len(allData)-len(flagEnd)] endAt = int64(readStartAt - len(flagStart)) } if len(embedData) != 0 { fmt.Println("Embed Data Found:") fmt.Println("=============") fmt.Println(string(embedData)) fmt.Println("=============") } var newEmbedData []byte if len(os.Args) > 1 { newEmbedData = []byte(os.Args[1]) } else { fmt.Println("Exit") return } newFile, err := os.CreateTemp(".", "new-*") if err != nil { panic("create temp file failed " + err.Error()) } //defer newFile.Close() _, err = selfFile.Seek(0, 0) if err != nil { panic("seek self to start failed " + err.Error()) } _, err = io.CopyN(newFile, selfFile, endAt) if err != nil && err != io.EOF { panic("copy self to new file failed " + err.Error()) } _, err = newFile.Write([]byte(flagStart)) if err != nil { panic("write new start flag failed " + err.Error()) } _, err = newFile.Write(newEmbedData) if err != nil { panic("write new embed data failed " + err.Error()) } _, err = newFile.Write([]byte(flagEnd)) if err != nil { panic("write new end flag failed " + err.Error()) } err = newFile.Close() if err != nil { panic("save new file failed " + err.Error()) } fmt.Println("new file saved to " + newFile.Name()) _ = os.Chmod(newFile.Name(), 0755) } func searchInReader(r io.Reader, data []byte) (int, error) { // production note: we cannot read whole file since it may be too large all, err := io.ReadAll(r) if err != nil { return -1, err } found := bytes.LastIndex(all, data) if found == -1 { return -1, fmt.Errorf("not found") } return found + len(data), nil }