├── ApacheLogs.txt ├── Chapter01 ├── hw.go └── unglyHW.go ├── Chapter02 ├── addCLA.go ├── array2map.go ├── arrays.go ├── breakMe.go ├── cla.go ├── dataStructures.go ├── defer.go ├── functions.go ├── hw.go ├── interfaces.go ├── maps.go ├── parameter.go ├── pointers.go ├── random.go └── slices.go ├── Chapter03 ├── addCLAImproved.go ├── cannotReach.go ├── findReplace.go ├── funErr.go ├── logging.go ├── occurrences.go ├── readColumn.go ├── reflection.go ├── regExp.go ├── summary.go └── unsafe.go ├── Chapter04 ├── garbageCol.go ├── hash.go ├── linkedList.go ├── privateFail.go ├── runTime.go ├── sortSlice.go ├── sources │ ├── aSimplePackage.go │ └── anotherPackage.go ├── tree.go ├── useMySQL.go └── usePackage.go ├── Chapter05 ├── cpStructure.go ├── excludeFind.go ├── finalFind.go ├── find.go ├── improvedFind.go ├── permissions.go ├── pwd.go ├── regExpFind.go ├── rename.go ├── rm.go ├── symbLink.go ├── traverse.go ├── traverseDir.go ├── usingFlag.go └── which.go ├── Chapter06 ├── bufIO.go ├── byteSlice.go ├── charByChar.go ├── cp.go ├── ddGo.go ├── fileLocking.go ├── fmtF.go ├── notGoodCP.go ├── readAll.go ├── readBinary.go ├── readColumn.go ├── readerWriter.go ├── records.go ├── sparse.go ├── tabSpace.go ├── usingIO.go └── wc.go ├── Chapter07 ├── appendData.go ├── countIP.go ├── dateTime.go ├── dateTimeLog.go ├── filePerm.go ├── findIP.go ├── findOG.go ├── findPerm.go ├── goodPass.go ├── insertLineNumber.go ├── listGroups.go ├── multipleMV.go ├── rotateLog.go ├── setFilePerm.go ├── swapRE.go ├── useSyslog.go ├── userFiles.go └── userID.go ├── Chapter08 ├── UNIXshell.go ├── catchAll.go ├── cpSignal.go ├── extractData.go ├── h1s.go ├── listProcess.go ├── plotData.go ├── plotIP.go ├── readSTDIN.go ├── readUNIX.go ├── rotateSignals.go └── writeSTDOUT.go ├── Chapter09 ├── aGoroutine.go ├── dWC.go ├── dWCtotal.go ├── dynamicGR.go ├── moreGoroutines.go ├── pipelines.go ├── readChannel.go ├── waitGR.go └── writeChannel.go ├── Chapter10 ├── WCbuffered.go ├── WCshared.go ├── bufChannels.go ├── cOfC.go ├── goMaxProcs.go ├── mutexRW.go ├── mutexSimple.go ├── nilChannel.go ├── rd.go ├── sharedMem.go ├── signalChannel.go ├── timeOuts.go ├── timeoutWait.go └── useSelect.go ├── Chapter11 ├── findKeyword.go ├── getURL.go ├── marUnmar.go ├── mongoDB.gohtml ├── readJSON.go ├── serveMux.go ├── showMongo.go ├── showMySQL.go ├── static.gohtml ├── template.go ├── template.gohtml ├── testMongo.go ├── timeoutHTTP.go ├── webClient.go ├── webServer.go └── writeJSON.go ├── Chapter12 ├── RPCclient.go ├── RPCserver.go ├── TCPc.go ├── TCPclient.go ├── TCPs.go ├── TCPserver.go ├── UDPclient.go ├── UDPserver.go ├── concTCP.go ├── handshake.pcap ├── lookHost.go ├── lookIP.go ├── lookNS.go ├── sharedRPC.go ├── socketClient.go └── socketServer.go ├── LICENSE └── README.md /ApacheLogs.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Go-Systems-Programming/81b8b0c039fc5870913436be5753378609727423/ApacheLogs.txt -------------------------------------------------------------------------------- /Chapter01/hw.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // This is a useless comment! 6 | func main() { 7 | fmt.Println("Hello World!") 8 | } 9 | -------------------------------------------------------------------------------- /Chapter01/unglyHW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import 4 | "fmt" 5 | 6 | // This is a useless comment! 7 | func main() { 8 | fmt.Println("Hello World!") 9 | 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Chapter02/addCLA.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | sum := 0 12 | for i := 1; i < len(arguments); i++ { 13 | temp, _ := strconv.Atoi(arguments[i]) 14 | sum = sum + temp 15 | } 16 | fmt.Println("Sum:", sum) 17 | } 18 | -------------------------------------------------------------------------------- /Chapter02/array2map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | anArray := [4]int{1, -2, 14, 0} 10 | aMap := make(map[string]int) 11 | 12 | length := len(anArray) 13 | for i := 0; i < length; i++ { 14 | fmt.Printf("%s ", strconv.Itoa(i)) 15 | aMap[strconv.Itoa(i)] = anArray[i] 16 | } 17 | fmt.Printf("\n") 18 | 19 | for key, value := range aMap { 20 | fmt.Printf("%s: %d\n", key, value) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter02/arrays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | myArray := [4]int{1, 2, 4, -4} 9 | length := len(myArray) 10 | for i := 0; i < length; i++ { 11 | fmt.Printf("%d ", myArray[i]) 12 | } 13 | fmt.Printf("\n") 14 | 15 | otherArray := [...]int{0, 2, -2, 6, 7, 8} 16 | for _, number := range otherArray { 17 | fmt.Printf("%d ", number) 18 | } 19 | fmt.Printf("\n") 20 | 21 | twoD := [3][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} 22 | twoD[1][2] = 15 23 | 24 | for _, number := range twoD { 25 | for _, other := range number { 26 | fmt.Printf("%d ", other) 27 | } 28 | } 29 | fmt.Printf("\n") 30 | 31 | threeD := [2][2][2]int{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}} 32 | threeD[0][1][1] = -1 33 | for _, number := range threeD { 34 | fmt.Printf("%d ", number) 35 | } 36 | fmt.Printf("\n") 37 | } 38 | -------------------------------------------------------------------------------- /Chapter02/breakMe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | myArray := [4]int{1, 2, 4, -4} 7 | threeD := [2][2][2]int{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}} 8 | fmt.Println("myArray[-1]:", myArray[-1]) 9 | fmt.Println("myArray[10]", myArray[10]) 10 | fmt.Println("threeD[-1][20][0]", threeD[-1][20][0]) 11 | } 12 | -------------------------------------------------------------------------------- /Chapter02/cla.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | arguments := os.Args 10 | for i := 0; i < len(arguments); i++ { 11 | fmt.Println(arguments[i]) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter02/dataStructures.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | 10 | type message struct { 11 | X int 12 | Y int 13 | Label string 14 | } 15 | 16 | p1 := message{23, 12, "A Message"} 17 | p2 := message{} 18 | p2.Label = "Message 2" 19 | 20 | s1 := reflect.ValueOf(&p1).Elem() 21 | s2 := reflect.ValueOf(&p2).Elem() 22 | fmt.Println("S2= ", s2) 23 | 24 | typeOfT := s1.Type() 25 | fmt.Println("P1=", p1) 26 | fmt.Println("P2=", p2) 27 | 28 | for i := 0; i < s1.NumField(); i++ { 29 | f := s1.Field(i) 30 | fmt.Printf("%d: %s ", i, typeOfT.Field(i).Name) 31 | fmt.Printf("%s = %v\n", f.Type(), f.Interface()) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Chapter02/defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func a1() { 8 | for i := 0; i < 3; i++ { 9 | defer fmt.Print(i, " ") 10 | } 11 | } 12 | 13 | func a2() { 14 | for i := 0; i < 3; i++ { 15 | defer func() { fmt.Print(i, " ") }() 16 | } 17 | } 18 | 19 | func a3() { 20 | for i := 0; i < 3; i++ { 21 | defer func(n int) { fmt.Print(n, " ") }(i) 22 | } 23 | } 24 | 25 | func main() { 26 | a1() 27 | fmt.Println() 28 | a2() 29 | fmt.Println() 30 | a3() 31 | fmt.Println() 32 | } 33 | -------------------------------------------------------------------------------- /Chapter02/functions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func unnamedMinMax(x, y int) (int, int) { 8 | if x > y { 9 | min := y 10 | max := x 11 | return min, max 12 | } else { 13 | min := x 14 | max := y 15 | return min, max 16 | } 17 | } 18 | 19 | func minMax(x, y int) (min, max int) { 20 | if x > y { 21 | min = y 22 | max = x 23 | } else { 24 | min = x 25 | max = y 26 | } 27 | return min, max 28 | } 29 | 30 | func namedMinMax(x, y int) (min, max int) { 31 | if x > y { 32 | min = y 33 | max = x 34 | } else { 35 | min = x 36 | max = y 37 | } 38 | return 39 | } 40 | 41 | func sort(x, y int) (int, int) { 42 | if x > y { 43 | return x, y 44 | } else { 45 | return y, x 46 | } 47 | } 48 | 49 | func main() { 50 | 51 | y := 4 52 | square := func(s int) int { 53 | return s * s 54 | } 55 | fmt.Println("The square of", y, "is", square(y)) 56 | 57 | square = func(s int) int { 58 | return s + s 59 | } 60 | fmt.Println("The square of", y, "is", square(y)) 61 | 62 | fmt.Println(minMax(15, 6)) 63 | fmt.Println(namedMinMax(15, 6)) 64 | min, max := namedMinMax(12, -1) 65 | fmt.Println(min, max) 66 | } 67 | -------------------------------------------------------------------------------- /Chapter02/hw.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("Hello World!") 7 | } 8 | -------------------------------------------------------------------------------- /Chapter02/interfaces.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type coordinates interface { 8 | xaxis() int 9 | yaxis() int 10 | } 11 | 12 | type point2D struct { 13 | X int 14 | Y int 15 | } 16 | 17 | func (s point2D) xaxis() int { 18 | return s.X 19 | } 20 | 21 | func (s point2D) yaxis() int { 22 | return s.Y 23 | } 24 | 25 | func findCoordinates(a coordinates) { 26 | fmt.Println("X:", a.xaxis(), "Y:", a.yaxis()) 27 | } 28 | 29 | type coordinate int 30 | 31 | func (s coordinate) xaxis() int { 32 | return int(s) 33 | } 34 | 35 | func (s coordinate) yaxis() int { 36 | return 0 37 | } 38 | 39 | func main() { 40 | 41 | x := point2D{X: -1, Y: 12} 42 | fmt.Println(x) 43 | findCoordinates(x) 44 | 45 | y := coordinate(10) 46 | findCoordinates(y) 47 | } 48 | -------------------------------------------------------------------------------- /Chapter02/maps.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | aMap := make(map[string]int) 10 | aMap["Mon"] = 0 11 | aMap["Tue"] = 1 12 | aMap["Wed"] = 2 13 | aMap["Thu"] = 3 14 | aMap["Fri"] = 4 15 | aMap["Sat"] = 5 16 | aMap["Sun"] = 6 17 | 18 | fmt.Printf("Sunday is the %dth day of the week.\n", aMap["Sun"]) 19 | 20 | // Check if a key exists on a Map 21 | _, ok := aMap["Tuesday"] 22 | if ok { 23 | fmt.Printf("The Tuesday key exists!\n") 24 | } else { 25 | fmt.Printf("The Tuesday key does not exist!\n") 26 | } 27 | 28 | count := 0 29 | // Visit all Map elements 30 | for key, _ := range aMap { 31 | count++ 32 | fmt.Printf("%s ", key) 33 | } 34 | fmt.Printf("\n") 35 | fmt.Printf("The aMap has %d elements\n", count) 36 | 37 | count = 0 38 | delete(aMap, "Fri") 39 | for _, _ = range aMap { 40 | count++ 41 | } 42 | fmt.Printf("The aMap has now %d elements\n", count) 43 | 44 | anotherMap := map[string]int{ 45 | "One": 1, 46 | "Two": 2, 47 | "Three": 3, 48 | "Four": 4, 49 | } 50 | anotherMap["Five"] = 5 51 | count = 0 52 | for _, _ = range anotherMap { 53 | count++ 54 | } 55 | fmt.Printf("anotherMap has %d elements\n", count) 56 | } 57 | -------------------------------------------------------------------------------- /Chapter02/parameter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | minusI := false 12 | for i := 0; i < len(arguments); i++ { 13 | if strings.Compare(arguments[i], "-i") == 0 { 14 | minusI = true 15 | break 16 | } 17 | } 18 | 19 | if minusI { 20 | fmt.Println("Got the -i parameter!") 21 | fmt.Print("y/n: ") 22 | var answer string 23 | fmt.Scanln(&answer) 24 | fmt.Println("You entered:", answer) 25 | } else { 26 | fmt.Println("The -i parameter is not set") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter02/pointers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func withPointer(x *int) { 8 | *x = *x * *x 9 | } 10 | 11 | type complex struct { 12 | x, y int 13 | } 14 | 15 | func newComplex(x, y int) *complex { 16 | return &complex{x, y} 17 | } 18 | 19 | func main() { 20 | x := -2 21 | withPointer(&x) 22 | fmt.Println(x) 23 | 24 | w := newComplex(4, -5) 25 | fmt.Println(*w) 26 | fmt.Println(w) 27 | } 28 | -------------------------------------------------------------------------------- /Chapter02/random.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func main() { 16 | MIN := 0 17 | MAX := 0 18 | TOTAL := 0 19 | if len(os.Args) > 3 { 20 | MIN, _ = strconv.Atoi(os.Args[1]) 21 | MAX, _ = strconv.Atoi(os.Args[2]) 22 | TOTAL, _ = strconv.Atoi(os.Args[3]) 23 | } else { 24 | fmt.Println("Usage:", os.Args[0], "MIX MAX TOTAL") 25 | os.Exit(-1) 26 | } 27 | 28 | rand.Seed(time.Now().Unix()) 29 | for i := 0; i < TOTAL; i++ { 30 | myrand := random(MIN, MAX) 31 | fmt.Print(myrand) 32 | fmt.Print(" ") 33 | } 34 | fmt.Println() 35 | } 36 | -------------------------------------------------------------------------------- /Chapter02/slices.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func change(x []int) { 8 | x[3] = -2 9 | } 10 | 11 | func printSlice(x []int) { 12 | for _, number := range x { 13 | fmt.Printf("%d ", number) 14 | } 15 | fmt.Println() 16 | } 17 | 18 | func main() { 19 | aSlice := []int{-1, 4, 5, 0, 7, 9} 20 | fmt.Printf("Before change: ") 21 | printSlice(aSlice) 22 | change(aSlice) 23 | fmt.Printf("After change: ") 24 | printSlice(aSlice) 25 | 26 | fmt.Printf("Before. Cap: %d, length: %d\n", cap(aSlice), len(aSlice)) 27 | aSlice = append(aSlice, -100) 28 | fmt.Printf("After. Cap: %d, length: %d\n", cap(aSlice), len(aSlice)) 29 | printSlice(aSlice) 30 | anotherSlice := make([]int, 4) 31 | fmt.Printf("A new slice with 4 elements: ") 32 | printSlice(anotherSlice) 33 | } 34 | -------------------------------------------------------------------------------- /Chapter03/addCLAImproved.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | sum := 0 12 | for i := 1; i < len(arguments); i++ { 13 | temp, err := strconv.Atoi(arguments[i]) 14 | if err == nil { 15 | sum = sum + temp 16 | } else { 17 | fmt.Println("Ignoring", arguments[i]) 18 | } 19 | } 20 | fmt.Println("Sum:", sum) 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/cannotReach.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func x() int { 8 | return -1 9 | fmt.Println("Exiting x()") 10 | } 11 | 12 | func y() int { 13 | return -1 14 | fmt.Println("Exiting y()") 15 | } 16 | 17 | func main() { 18 | fmt.Println(x()) 19 | fmt.Println("Exiting program...") 20 | } 21 | -------------------------------------------------------------------------------- /Chapter03/findReplace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | ) 8 | 9 | func main() { 10 | 11 | var s [3]string 12 | s[0] = "1 b 3" 13 | s[1] = "11 a B 14 1 1" 14 | s[2] = "b 2 -3 B -5" 15 | 16 | parse, err := regexp.Compile("[bB]") 17 | 18 | if err != nil { 19 | fmt.Printf("Error compiling RE: %s\n", err) 20 | os.Exit(-1) 21 | } 22 | 23 | for i := 0; i < len(s); i++ { 24 | temp := parse.ReplaceAllString(s[i], "C") 25 | fmt.Println(temp) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter03/funErr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "log" 7 | ) 8 | 9 | func division(x, y int) (int, error, error) { 10 | if y == 0 { 11 | return 0, nil, errors.New("Cannot divide by zero!") 12 | } 13 | if x%y != 0 { 14 | remainder := errors.New("There is a remainder!") 15 | return x / y, remainder, nil 16 | } else { 17 | return x / y, nil, nil 18 | } 19 | 20 | } 21 | 22 | func main() { 23 | result, rem, err := division(2, 2) 24 | if err != nil { 25 | log.Fatal(err) 26 | } else { 27 | fmt.Println("The result is", result) 28 | } 29 | 30 | if rem != nil { 31 | fmt.Println(rem) 32 | } 33 | 34 | result, rem, err = division(12, 5) 35 | if err != nil { 36 | log.Fatal(err) 37 | } else { 38 | fmt.Println("The result is", result) 39 | } 40 | 41 | if rem != nil { 42 | fmt.Println(rem) 43 | } 44 | 45 | result, rem, err = division(2, 0) 46 | if err != nil { 47 | log.Fatal(err) 48 | } else { 49 | fmt.Println("The result is", result) 50 | } 51 | 52 | if rem != nil { 53 | fmt.Println(rem) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Chapter03/logging.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | func main() { 8 | x := 1 9 | log.Printf("log.Print() function: %d", x) 10 | x = x + 1 11 | log.Printf("log.Print() function: %d", x) 12 | x = x + 1 13 | log.Panicf("log.Panicf() function: %d", x) 14 | x = x + 1 15 | log.Printf("log.Print() function: %d", x) 16 | } 17 | -------------------------------------------------------------------------------- /Chapter03/occurrences.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | 10 | var s [3]string 11 | s[0] = "1 b 3 1 a a b" 12 | s[1] = "11 a 1 1 1 1 a a" 13 | s[2] = "-1 b 1 -4 a 1" 14 | 15 | counts := make(map[string]int) 16 | 17 | for i := 0; i < len(s); i++ { 18 | data := strings.Fields(s[i]) 19 | for _, word := range data { 20 | _, ok := counts[word] 21 | if ok { 22 | counts[word] = counts[word] + 1 23 | } else { 24 | counts[word] = 1 25 | } 26 | } 27 | } 28 | 29 | for key, _ := range counts { 30 | fmt.Printf("%s -> %d \n", key, counts[key]) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter03/readColumn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | var s [3]string 10 | s[0] = "1 2 3" 11 | s[1] = "11 12 13 14 15 16" 12 | s[2] = "-1 2 -3 -4 -5 6" 13 | 14 | column := 2 15 | 16 | for i := 0; i < len(s); i++ { 17 | data := strings.Fields(s[i]) 18 | if len(data) >= column { 19 | fmt.Println((data[column-1])) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter03/reflection.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | 10 | type t1 int 11 | type t2 int 12 | 13 | x1 := t1(1) 14 | x2 := t2(1) 15 | x3 := 1 16 | 17 | st1 := reflect.ValueOf(&x1).Elem() 18 | st2 := reflect.ValueOf(&x2).Elem() 19 | st3 := reflect.ValueOf(&x3).Elem() 20 | 21 | typeOfX1 := st1.Type() 22 | typeOfX2 := st2.Type() 23 | typeOfX3 := st3.Type() 24 | 25 | fmt.Printf("X1 Type: %s\n", typeOfX1) 26 | fmt.Printf("X2 Type: %s\n", typeOfX2) 27 | fmt.Printf("X3 Type: %s\n", typeOfX3) 28 | 29 | type aStructure struct { 30 | X uint 31 | Y float64 32 | Text string 33 | } 34 | 35 | x4 := aStructure{123, 3.14, "A Structure"} 36 | st4 := reflect.ValueOf(&x4).Elem() 37 | typeOfX4 := st4.Type() 38 | 39 | fmt.Printf("X4 Type: %s\n", typeOfX4) 40 | fmt.Printf("The fields of %s are:\n", typeOfX4) 41 | 42 | for i := 0; i < st4.NumField(); i++ { 43 | fmt.Printf("%d: Field name: %s ", i, typeOfX4.Field(i).Name) 44 | fmt.Printf("Type: %s ", st4.Field(i).Type()) 45 | fmt.Printf("and Value: %v\n", st4.Field(i).Interface()) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chapter03/regExp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | ) 7 | 8 | func main() { 9 | match, _ := regexp.MatchString("Mihalis", "Mihalis Tsoukalos") 10 | fmt.Println(match) 11 | match, _ = regexp.MatchString("Tsoukalos", "Mihalis tsoukalos") 12 | fmt.Println(match) 13 | 14 | parse, err := regexp.Compile("[Mm]ihalis") 15 | 16 | if err != nil { 17 | fmt.Printf("Error compiling RE: %s\n", err) 18 | } else { 19 | fmt.Println(parse.MatchString("Mihalis Tsoukalos")) 20 | fmt.Println(parse.MatchString("mihalis Tsoukalos")) 21 | fmt.Println(parse.MatchString("M ihalis Tsoukalos")) 22 | fmt.Println(parse.ReplaceAllString("mihalis Mihalis", "MIHALIS")) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter03/summary.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | var s [3]string 12 | s[0] = "1 b 3" 13 | s[1] = "11 a 1 14 1 1" 14 | s[2] = "-1 2 -3 -4 -5" 15 | 16 | arguments := os.Args 17 | column, err := strconv.Atoi(arguments[1]) 18 | if err != nil { 19 | fmt.Println("Error reading argument") 20 | os.Exit(-1) 21 | } 22 | if column == 0 { 23 | fmt.Println("Invalid column") 24 | os.Exit(1) 25 | } 26 | 27 | sum := 0 28 | for i := 0; i < len(s); i++ { 29 | data := strings.Fields(s[i]) 30 | if len(data) >= column { 31 | temp, err := strconv.Atoi(data[column-1]) 32 | if err == nil { 33 | sum = sum + temp 34 | } else { 35 | fmt.Printf("Invalid argument: %s\n", data[column-1]) 36 | } 37 | } else { 38 | fmt.Println("Invalid column!") 39 | } 40 | } 41 | fmt.Printf("Sum: %d\n", sum) 42 | } 43 | -------------------------------------------------------------------------------- /Chapter03/unsafe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var value int64 = 5.0 10 | var p1 = &value 11 | var p2 = (*int32)(unsafe.Pointer(p1)) 12 | 13 | fmt.Println("*p1: ", *p1) 14 | fmt.Println("*p2: ", *p2) 15 | *p1 = 312121321321213212 16 | fmt.Println(value) 17 | fmt.Println("*p2: ", *p2) 18 | *p1 = 31212132 19 | fmt.Println(value) 20 | fmt.Println("*p2: ", *p2) 21 | } 22 | -------------------------------------------------------------------------------- /Chapter04/garbageCol.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func printStats(mem runtime.MemStats) { 10 | runtime.ReadMemStats(&mem) 11 | fmt.Println("mem.Alloc:", mem.Alloc) 12 | fmt.Println("mem.TotalAlloc:", mem.TotalAlloc) 13 | fmt.Println("mem.HeapAlloc:", mem.HeapAlloc) 14 | fmt.Println("mem.NumGC:", mem.NumGC) 15 | fmt.Println("-----") 16 | } 17 | 18 | func main() { 19 | var mem runtime.MemStats 20 | printStats(mem) 21 | 22 | for i := 0; i < 10; i++ { 23 | s := make([]byte, 100000000) 24 | if s == nil { 25 | fmt.Println("Operation failed!") 26 | } 27 | } 28 | printStats(mem) 29 | 30 | for i := 0; i < 10; i++ { 31 | s := make([]byte, 100000000) 32 | if s == nil { 33 | fmt.Println("Operation failed!") 34 | } 35 | time.Sleep(5 * time.Second) 36 | } 37 | printStats(mem) 38 | } 39 | -------------------------------------------------------------------------------- /Chapter04/hash.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | type HashTable struct { 13 | Table map[int]*Node 14 | Size int 15 | } 16 | 17 | func hashFunction(i, size int) int { 18 | return (i % size) 19 | } 20 | 21 | func insert(hash *HashTable, value int) int { 22 | index := hashFunction(value, hash.Size) 23 | element := Node{Value: value, Next: hash.Table[index]} 24 | hash.Table[index] = &element 25 | return index 26 | } 27 | 28 | func traverse(hash *HashTable) { 29 | for k := range hash.Table { 30 | if hash.Table[k] != nil { 31 | t := hash.Table[k] 32 | for t != nil { 33 | fmt.Printf("%d -> ", t.Value) 34 | t = t.Next 35 | } 36 | fmt.Println() 37 | } 38 | } 39 | } 40 | 41 | func main() { 42 | table := make(map[int]*Node, 10) 43 | hash := &HashTable{Table: table, Size: 10} 44 | fmt.Println("Number of spaces:", hash.Size) 45 | for i := 0; i < 95; i++ { 46 | insert(hash, i) 47 | } 48 | traverse(hash) 49 | } 50 | -------------------------------------------------------------------------------- /Chapter04/linkedList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | func addNode(t *Node, v int) int { 13 | if root == nil { 14 | t = &Node{v, nil} 15 | root = t 16 | return 0 17 | } 18 | 19 | if v == t.Value { 20 | fmt.Println("Node already exists:", v) 21 | return -1 22 | } 23 | 24 | if t.Next == nil { 25 | t.Next = &Node{v, nil} 26 | return -2 27 | } 28 | 29 | return addNode(t.Next, v) 30 | } 31 | 32 | func traverse(t *Node) { 33 | if t == nil { 34 | fmt.Println("-> Empty list!") 35 | return 36 | } 37 | 38 | for t != nil { 39 | fmt.Printf("%d -> ", t.Value) 40 | t = t.Next 41 | } 42 | fmt.Println() 43 | } 44 | 45 | var root = new(Node) 46 | 47 | func main() { 48 | fmt.Println(root) 49 | root = nil 50 | traverse(root) 51 | addNode(root, 1) 52 | addNode(root, 1) 53 | traverse(root) 54 | addNode(root, 10) 55 | addNode(root, 5) 56 | addNode(root, 0) 57 | addNode(root, 0) 58 | traverse(root) 59 | addNode(root, 100) 60 | traverse(root) 61 | } 62 | -------------------------------------------------------------------------------- /Chapter04/privateFail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "anotherPackage" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | anotherPackage.Version() 10 | // fmt.Println(anotherPackage.version) 11 | fmt.Println(anotherPackage.Pi) 12 | } 13 | -------------------------------------------------------------------------------- /Chapter04/runTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("You are using ", runtime.Compiler, " ") 10 | fmt.Println("on a", runtime.GOARCH, "machine") 11 | fmt.Println("with Go version", runtime.Version()) 12 | fmt.Println("Number of Goroutines:", runtime.NumGoroutine()) 13 | } 14 | -------------------------------------------------------------------------------- /Chapter04/sortSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type aStructure struct { 9 | person string 10 | height int 11 | weight int 12 | } 13 | 14 | func main() { 15 | 16 | mySlice := make([]aStructure, 0) 17 | a := aStructure{"Mihalis", 180, 90} 18 | mySlice = append(mySlice, a) 19 | a = aStructure{"Dimitris", 180, 95} 20 | mySlice = append(mySlice, a) 21 | a = aStructure{"Marietta", 155, 45} 22 | mySlice = append(mySlice, a) 23 | a = aStructure{"Bill", 134, 40} 24 | mySlice = append(mySlice, a) 25 | 26 | fmt.Println("0:", mySlice) 27 | sort.Slice(mySlice, func(i, j int) bool { 28 | return mySlice[i].weight < mySlice[j].weight 29 | }) 30 | fmt.Println("<:", mySlice) 31 | sort.Slice(mySlice, func(i, j int) bool { 32 | return mySlice[i].weight > mySlice[j].weight 33 | }) 34 | fmt.Println(">:", mySlice) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Chapter04/sources/aSimplePackage.go: -------------------------------------------------------------------------------- 1 | package aSimplePackage 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const Pi = "3.14159" 8 | 9 | func Add(x, y int) int { 10 | return x + y 11 | } 12 | 13 | func Println(x int) { 14 | fmt.Println(x) 15 | } 16 | -------------------------------------------------------------------------------- /Chapter04/sources/anotherPackage.go: -------------------------------------------------------------------------------- 1 | package anotherPackage 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const Pi = "3.14159" 8 | const version = "1.1" 9 | 10 | func Add(x, y int) int { 11 | return x + y 12 | } 13 | 14 | func Println(x int) { 15 | fmt.Println(x) 16 | } 17 | 18 | func Version() { 19 | fmt.Println("The version of the package is", version) 20 | } 21 | 22 | func init() { 23 | fmt.Println("The init function of anotherPackage") 24 | } 25 | -------------------------------------------------------------------------------- /Chapter04/tree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | type Tree struct { 10 | Left *Tree 11 | Value int 12 | Right *Tree 13 | } 14 | 15 | func traverse(t *Tree) { 16 | if t == nil { 17 | return 18 | } 19 | traverse(t.Left) 20 | fmt.Print(t.Value, " ") 21 | traverse(t.Right) 22 | } 23 | 24 | func create(n int) *Tree { 25 | var t *Tree 26 | rand.Seed(time.Now().Unix()) 27 | for i := 0; i < 2*n; i++ { 28 | temp := rand.Intn(n) 29 | t = insert(t, temp) 30 | } 31 | return t 32 | } 33 | 34 | func insert(t *Tree, v int) *Tree { 35 | if t == nil { 36 | return &Tree{nil, v, nil} 37 | } 38 | if v == t.Value { 39 | return t 40 | } 41 | if v < t.Value { 42 | t.Left = insert(t.Left, v) 43 | return t 44 | } 45 | t.Right = insert(t.Right, v) 46 | return t 47 | } 48 | 49 | func main() { 50 | tree := create(30) 51 | traverse(tree) 52 | fmt.Println() 53 | fmt.Println("The value of the root of the tree is", tree.Value) 54 | } 55 | -------------------------------------------------------------------------------- /Chapter04/useMySQL.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | _ "github.com/go-sql-driver/mysql" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Using the MySQL Go driver!") 10 | } 11 | -------------------------------------------------------------------------------- /Chapter04/usePackage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "aSimplePackage" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | temp := aSimplePackage.Add(5, 10) 10 | fmt.Println(temp) 11 | fmt.Println(aSimplePackage.Pi) 12 | } 13 | -------------------------------------------------------------------------------- /Chapter05/cpStructure.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | minusTEST := flag.Bool("test", false, "Test run!") 13 | 14 | flag.Parse() 15 | flags := flag.Args() 16 | 17 | if len(flags) == 0 || len(flags) == 1 { 18 | fmt.Println("Not enough arguments!") 19 | os.Exit(1) 20 | } 21 | 22 | Path := flags[0] 23 | NewPath := flags[1] 24 | 25 | permissions := os.ModePerm 26 | _, err := os.Stat(NewPath) 27 | if os.IsNotExist(err) { 28 | os.MkdirAll(NewPath, permissions) 29 | } else { 30 | fmt.Println(NewPath, "already exists - quitting...") 31 | os.Exit(1) 32 | } 33 | 34 | walkFunction := func(currentPath string, info os.FileInfo, err error) error { 35 | fileInfo, _ := os.Lstat(currentPath) 36 | if fileInfo.Mode()&os.ModeSymlink != 0 { 37 | fmt.Println("Skipping", currentPath) 38 | return nil 39 | } 40 | 41 | fileInfo, err = os.Stat(currentPath) 42 | if err != nil { 43 | fmt.Println("*", err) 44 | return err 45 | } 46 | 47 | mode := fileInfo.Mode() 48 | if mode.IsDir() { 49 | tempPath := strings.Replace(currentPath, Path, "", 1) 50 | pathToCreate := NewPath + "/" + filepath.Base(Path) + tempPath 51 | 52 | if *minusTEST { 53 | fmt.Println(":", pathToCreate) 54 | return nil 55 | } 56 | 57 | _, err := os.Stat(pathToCreate) 58 | if os.IsNotExist(err) { 59 | os.MkdirAll(pathToCreate, permissions) 60 | } else { 61 | fmt.Println("Did not create", pathToCreate, ":", err) 62 | } 63 | } 64 | return nil 65 | } 66 | 67 | err = filepath.Walk(Path, walkFunction) 68 | if err != nil { 69 | fmt.Println(err) 70 | os.Exit(1) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Chapter05/excludeFind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | func excludeNames(name string, exclude string) bool { 11 | if exclude == "" { 12 | return false 13 | } 14 | if filepath.Base(name) == exclude { 15 | return true 16 | } 17 | return false 18 | } 19 | 20 | func main() { 21 | 22 | minusS := flag.Bool("s", false, "Sockets") 23 | minusP := flag.Bool("p", false, "Pipes") 24 | minusSL := flag.Bool("sl", false, "Symbolic Links") 25 | minusD := flag.Bool("d", false, "Directories") 26 | minusF := flag.Bool("f", false, "Files") 27 | minusX := flag.String("x", "", "Files") 28 | 29 | flag.Parse() 30 | flags := flag.Args() 31 | 32 | printAll := false 33 | if *minusS && *minusP && *minusSL && *minusD && *minusF { 34 | printAll = true 35 | } 36 | 37 | if !(*minusS || *minusP || *minusSL || *minusD || *minusF) { 38 | printAll = true 39 | } 40 | 41 | if len(flags) == 0 { 42 | fmt.Println("Not enough arguments!") 43 | os.Exit(1) 44 | } 45 | 46 | Path := flags[0] 47 | 48 | walkFunction := func(path string, info os.FileInfo, err error) error { 49 | fileInfo, err := os.Stat(path) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | if excludeNames(path, *minusX) { 55 | return nil 56 | } 57 | 58 | if printAll == true { 59 | fmt.Println(path) 60 | return nil 61 | } 62 | 63 | mode := fileInfo.Mode() 64 | if mode.IsRegular() && *minusF { 65 | fmt.Println(path) 66 | return nil 67 | } 68 | 69 | if mode.IsDir() && *minusD { 70 | fmt.Println(path) 71 | return nil 72 | } 73 | 74 | fileInfo, _ = os.Lstat(path) 75 | if fileInfo.Mode()&os.ModeSymlink != 0 { 76 | if *minusSL { 77 | fmt.Println(path) 78 | return nil 79 | } 80 | } 81 | 82 | if fileInfo.Mode()&os.ModeNamedPipe != 0 { 83 | if *minusP { 84 | fmt.Println(path) 85 | return nil 86 | } 87 | } 88 | 89 | if fileInfo.Mode()&os.ModeSocket != 0 { 90 | if *minusS { 91 | fmt.Println(path) 92 | return nil 93 | } 94 | } 95 | 96 | return nil 97 | } 98 | 99 | err := filepath.Walk(Path, walkFunction) 100 | if err != nil { 101 | fmt.Println(err) 102 | os.Exit(1) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Chapter05/finalFind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | func excludeNames(name string, exclude string) bool { 12 | if exclude == "" { 13 | return false 14 | } 15 | if filepath.Base(name) == exclude { 16 | return true 17 | } 18 | return false 19 | } 20 | 21 | func excludeExtensions(name string, extension string) bool { 22 | if extension == "" { 23 | return false 24 | } 25 | basename := filepath.Base(name) 26 | s := strings.Split(basename, ".") 27 | length := len(s) 28 | basenameExtension := s[length-1] 29 | if basenameExtension == extension { 30 | return true 31 | } 32 | return false 33 | } 34 | 35 | func main() { 36 | 37 | minusS := flag.Bool("s", false, "Sockets") 38 | minusP := flag.Bool("p", false, "Pipes") 39 | minusSL := flag.Bool("sl", false, "Symbolic Links") 40 | minusD := flag.Bool("d", false, "Directories") 41 | minusF := flag.Bool("f", false, "Files") 42 | minusX := flag.String("x", "", "Files") 43 | minusEXT := flag.String("ext", "", "Extensions") 44 | 45 | flag.Parse() 46 | flags := flag.Args() 47 | 48 | printAll := false 49 | if *minusS && *minusP && *minusSL && *minusD && *minusF { 50 | printAll = true 51 | } 52 | 53 | if !(*minusS || *minusP || *minusSL || *minusD || *minusF) { 54 | printAll = true 55 | } 56 | 57 | if len(flags) == 0 { 58 | fmt.Println("Not enough arguments!") 59 | os.Exit(1) 60 | } 61 | 62 | Path := flags[0] 63 | 64 | walkFunction := func(path string, info os.FileInfo, err error) error { 65 | fileInfo, err := os.Stat(path) 66 | if err != nil { 67 | return err 68 | } 69 | 70 | if excludeNames(path, *minusX) { 71 | return nil 72 | } 73 | 74 | if excludeExtensions(path, *minusEXT) { 75 | return nil 76 | } 77 | 78 | if printAll == true { 79 | fmt.Println(path) 80 | return nil 81 | } 82 | 83 | mode := fileInfo.Mode() 84 | if mode.IsRegular() && *minusF { 85 | fmt.Println(path) 86 | return nil 87 | } 88 | 89 | if mode.IsDir() && *minusD { 90 | fmt.Println(path) 91 | return nil 92 | } 93 | 94 | fileInfo, _ = os.Lstat(path) 95 | if fileInfo.Mode()&os.ModeSymlink != 0 { 96 | if *minusSL { 97 | fmt.Println(path) 98 | return nil 99 | } 100 | } 101 | 102 | if fileInfo.Mode()&os.ModeNamedPipe != 0 { 103 | if *minusP { 104 | fmt.Println(path) 105 | return nil 106 | } 107 | } 108 | 109 | if fileInfo.Mode()&os.ModeSocket != 0 { 110 | if *minusS { 111 | fmt.Println(path) 112 | return nil 113 | } 114 | } 115 | 116 | return nil 117 | } 118 | 119 | err := filepath.Walk(Path, walkFunction) 120 | if err != nil { 121 | fmt.Println(err) 122 | os.Exit(1) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Chapter05/find.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | func walkFunction(path string, info os.FileInfo, err error) error { 11 | 12 | fileInfo, err := os.Stat(path) 13 | if err != nil { 14 | return err 15 | } 16 | 17 | mode := fileInfo.Mode() 18 | if mode.IsDir() || mode.IsRegular() { 19 | fmt.Println(path) 20 | } 21 | return nil 22 | } 23 | 24 | func main() { 25 | flag.Parse() 26 | flags := flag.Args() 27 | 28 | if len(flags) == 0 { 29 | fmt.Println("Not enough arguments!") 30 | os.Exit(1) 31 | } 32 | 33 | Path := flags[0] 34 | err := filepath.Walk(Path, walkFunction) 35 | if err != nil { 36 | fmt.Println(err) 37 | os.Exit(1) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chapter05/improvedFind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | func main() { 11 | 12 | minusS := flag.Bool("s", false, "Sockets") 13 | minusP := flag.Bool("p", false, "Pipes") 14 | minusSL := flag.Bool("sl", false, "Symbolic Links") 15 | minusD := flag.Bool("d", false, "Directories") 16 | minusF := flag.Bool("f", false, "Files") 17 | 18 | flag.Parse() 19 | flags := flag.Args() 20 | 21 | printAll := false 22 | if *minusS && *minusP && *minusSL && *minusD && *minusF { 23 | printAll = true 24 | } 25 | 26 | if !(*minusS || *minusP || *minusSL || *minusD || *minusF) { 27 | printAll = true 28 | } 29 | 30 | if len(flags) == 0 { 31 | fmt.Println("Not enough arguments!") 32 | os.Exit(1) 33 | } 34 | 35 | Path := flags[0] 36 | 37 | walkFunction := func(path string, info os.FileInfo, err error) error { 38 | fileInfo, err := os.Stat(path) 39 | if err != nil { 40 | return err 41 | } 42 | 43 | if printAll == true { 44 | fmt.Println(path) 45 | return nil 46 | } 47 | 48 | mode := fileInfo.Mode() 49 | if mode.IsRegular() && *minusF { 50 | fmt.Println(path) 51 | return nil 52 | } 53 | 54 | if mode.IsDir() && *minusD { 55 | fmt.Println(path) 56 | return nil 57 | } 58 | 59 | fileInfo, _ = os.Lstat(path) 60 | if fileInfo.Mode()&os.ModeSymlink != 0 { 61 | if *minusSL { 62 | fmt.Println(path) 63 | return nil 64 | } 65 | } 66 | 67 | if fileInfo.Mode()&os.ModeNamedPipe != 0 { 68 | if *minusP { 69 | fmt.Println(path) 70 | return nil 71 | } 72 | } 73 | 74 | if fileInfo.Mode()&os.ModeSocket != 0 { 75 | if *minusS { 76 | fmt.Println(path) 77 | return nil 78 | } 79 | } 80 | 81 | return nil 82 | } 83 | 84 | err := filepath.Walk(Path, walkFunction) 85 | if err != nil { 86 | fmt.Println(err) 87 | os.Exit(1) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Chapter05/permissions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | arguments := os.Args 10 | if len(arguments) == 1 { 11 | fmt.Println("Please provide an argument!") 12 | os.Exit(1) 13 | } 14 | 15 | file := arguments[1] 16 | info, err := os.Stat(file) 17 | if err != nil { 18 | fmt.Println("Error:", err) 19 | os.Exit(1) 20 | } 21 | mode := info.Mode() 22 | fmt.Print(file, ": ", mode, "\n") 23 | } 24 | -------------------------------------------------------------------------------- /Chapter05/pwd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | 12 | pwd, err := os.Getwd() 13 | if err == nil { 14 | fmt.Println(pwd) 15 | } else { 16 | fmt.Println("Error:", err) 17 | } 18 | 19 | if len(arguments) == 1 { 20 | return 21 | } 22 | 23 | if arguments[1] != "-P" { 24 | return 25 | } 26 | 27 | fileinfo, err := os.Lstat(pwd) 28 | if fileinfo.Mode()&os.ModeSymlink != 0 { 29 | realpath, err := filepath.EvalSymlinks(pwd) 30 | if err == nil { 31 | fmt.Println(realpath) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chapter05/regExpFind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "regexp" 9 | "strings" 10 | ) 11 | 12 | func excludeNames(name string, exclude string) bool { 13 | if exclude == "" { 14 | return false 15 | } 16 | if filepath.Base(name) == exclude { 17 | return true 18 | } 19 | return false 20 | } 21 | 22 | func excludeExtensions(name string, extension string) bool { 23 | if extension == "" { 24 | return false 25 | } 26 | basename := filepath.Base(name) 27 | s := strings.Split(basename, ".") 28 | length := len(s) 29 | basenameExtension := s[length-1] 30 | if basenameExtension == extension { 31 | return true 32 | } 33 | return false 34 | } 35 | 36 | func regularExpression(path, regExp string) bool { 37 | if regExp == "" { 38 | return true 39 | } 40 | r, _ := regexp.Compile(regExp) 41 | matched := r.MatchString(path) 42 | return matched 43 | } 44 | 45 | func main() { 46 | 47 | minusS := flag.Bool("s", false, "Sockets") 48 | minusP := flag.Bool("p", false, "Pipes") 49 | minusSL := flag.Bool("sl", false, "Symbolic Links") 50 | minusD := flag.Bool("d", false, "Directories") 51 | minusF := flag.Bool("f", false, "Files") 52 | minusX := flag.String("x", "", "Files") 53 | minusEXT := flag.String("ext", "", "Extensions") 54 | minusRE := flag.String("re", "", "Regular Expression") 55 | 56 | flag.Parse() 57 | flags := flag.Args() 58 | 59 | printAll := false 60 | if *minusS && *minusP && *minusSL && *minusD && *minusF { 61 | printAll = true 62 | } 63 | 64 | if !(*minusS || *minusP || *minusSL || *minusD || *minusF) { 65 | printAll = true 66 | } 67 | 68 | if len(flags) == 0 { 69 | fmt.Println("Not enough arguments!") 70 | os.Exit(1) 71 | } 72 | Path := flags[0] 73 | 74 | walkFunction := func(path string, info os.FileInfo, err error) error { 75 | if regularExpression(path, *minusRE) == false { 76 | return nil 77 | } 78 | 79 | fileInfo, err := os.Stat(path) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | if excludeNames(path, *minusX) { 85 | return nil 86 | } 87 | 88 | if excludeExtensions(path, *minusEXT) { 89 | return nil 90 | } 91 | 92 | if printAll == true { 93 | fmt.Println(path) 94 | return nil 95 | } 96 | 97 | mode := fileInfo.Mode() 98 | if mode.IsRegular() && *minusF { 99 | fmt.Println(path) 100 | return nil 101 | } 102 | 103 | if mode.IsDir() && *minusD { 104 | fmt.Println(path) 105 | return nil 106 | } 107 | 108 | fileInfo, _ = os.Lstat(path) 109 | if fileInfo.Mode()&os.ModeSymlink != 0 { 110 | if *minusSL { 111 | fmt.Println(path) 112 | return nil 113 | } 114 | } 115 | 116 | if fileInfo.Mode()&os.ModeNamedPipe != 0 { 117 | if *minusP { 118 | fmt.Println(path) 119 | return nil 120 | } 121 | } 122 | 123 | if fileInfo.Mode()&os.ModeSocket != 0 { 124 | if *minusS { 125 | fmt.Println(path) 126 | return nil 127 | } 128 | } 129 | 130 | return nil 131 | } 132 | 133 | err := filepath.Walk(Path, walkFunction) 134 | if err != nil { 135 | fmt.Println(err) 136 | os.Exit(1) 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Chapter05/rename.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | func main() { 11 | minusOverwrite := flag.Bool("overwrite", false, "overwrite") 12 | 13 | flag.Parse() 14 | flags := flag.Args() 15 | 16 | if len(flags) < 2 { 17 | fmt.Println("Please provide two arguments!") 18 | os.Exit(1) 19 | } 20 | 21 | source := flags[0] 22 | destination := flags[1] 23 | fileInfo, err := os.Stat(source) 24 | if err == nil { 25 | mode := fileInfo.Mode() 26 | if mode.IsRegular() == false { 27 | fmt.Println("Sorry, we only support regular files as source!") 28 | os.Exit(1) 29 | } 30 | } else { 31 | fmt.Println("Error reading:", source) 32 | os.Exit(1) 33 | } 34 | 35 | newDestination := destination 36 | destInfo, err := os.Stat(destination) 37 | if err == nil { 38 | mode := destInfo.Mode() 39 | if mode.IsDir() { 40 | justTheName := filepath.Base(source) 41 | newDestination = destination + "/" + justTheName 42 | } 43 | } 44 | 45 | destination = newDestination 46 | destInfo, err = os.Stat(destination) 47 | if err == nil { 48 | if *minusOverwrite == false { 49 | fmt.Println("Destination file already exists!") 50 | os.Exit(1) 51 | } 52 | } 53 | 54 | err = os.Rename(source, destination) 55 | if err != nil { 56 | fmt.Println(err) 57 | os.Exit(1) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter05/rm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | arguments := os.Args 10 | if len(arguments) == 1 { 11 | fmt.Println("Please provide an argument!") 12 | os.Exit(1) 13 | } 14 | 15 | file := arguments[1] 16 | err := os.Remove(file) 17 | if err != nil { 18 | fmt.Println(err) 19 | return 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter05/symbLink.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide an argument!") 13 | os.Exit(1) 14 | } 15 | filename := arguments[1] 16 | 17 | fileinfo, err := os.Lstat(filename) 18 | if err != nil { 19 | fmt.Println(err) 20 | os.Exit(1) 21 | } 22 | 23 | if fileinfo.Mode()&os.ModeSymlink != 0 { 24 | fmt.Println(filename, "is a symbolic link") 25 | realpath, err := filepath.EvalSymlinks(filename) 26 | if err == nil { 27 | fmt.Println("Path:", realpath) 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Chapter05/traverse.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func walkFunction(path string, info os.FileInfo, err error) error { 10 | _, err = os.Stat(path) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | fmt.Println(path) 16 | return nil 17 | } 18 | 19 | func main() { 20 | arguments := os.Args 21 | if len(arguments) == 1 { 22 | fmt.Println("Not enough arguments!") 23 | os.Exit(1) 24 | } 25 | 26 | Path := arguments[1] 27 | err := filepath.Walk(Path, walkFunction) 28 | if err != nil { 29 | fmt.Println(err) 30 | os.Exit(1) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter05/traverseDir.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func walkFunction(path string, info os.FileInfo, err error) error { 10 | fileInfo, err := os.Stat(path) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | mode := fileInfo.Mode() 16 | if mode.IsDir() { 17 | fmt.Println(path) 18 | } 19 | return nil 20 | } 21 | 22 | func main() { 23 | arguments := os.Args 24 | if len(arguments) == 1 { 25 | fmt.Println("Not enough arguments!") 26 | os.Exit(1) 27 | } 28 | 29 | Path := arguments[1] 30 | err := filepath.Walk(Path, walkFunction) 31 | if err != nil { 32 | fmt.Println(err) 33 | os.Exit(1) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter05/usingFlag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | minusO := flag.Bool("o", false, "o") 10 | minusC := flag.Bool("c", false, "c") 11 | minusK := flag.Int("k", 0, "an int") 12 | 13 | flag.Parse() 14 | 15 | fmt.Println("-o:", *minusO) 16 | fmt.Println("-c:", *minusC) 17 | fmt.Println("-K:", *minusK) 18 | 19 | for index, val := range flag.Args() { 20 | fmt.Println(index, ":", val) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter05/which.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | minusA := flag.Bool("a", false, "a") 12 | minusS := flag.Bool("s", false, "s") 13 | 14 | flag.Parse() 15 | flags := flag.Args() 16 | if len(flags) == 0 { 17 | fmt.Println("Please provide an argument!") 18 | os.Exit(1) 19 | } 20 | file := flags[0] 21 | fountIt := false 22 | 23 | path := os.Getenv("PATH") 24 | pathSlice := strings.Split(path, ":") 25 | for _, directory := range pathSlice { 26 | fullPath := directory + "/" + file 27 | // Does it exist? 28 | fileInfo, err := os.Stat(fullPath) 29 | if err == nil { 30 | mode := fileInfo.Mode() 31 | // Is it a regular file? 32 | if mode.IsRegular() { 33 | // Is it executable? 34 | if mode&0111 != 0 { 35 | fountIt = true 36 | // if the -s flag is set 37 | if *minusS == true { 38 | os.Exit(0) 39 | } 40 | // if the -a flag is set 41 | if *minusA == true { 42 | fmt.Println(fullPath) 43 | } else { 44 | fmt.Println(fullPath) 45 | os.Exit(0) 46 | } 47 | } 48 | } 49 | } 50 | } 51 | if fountIt == false { 52 | os.Exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Chapter06/bufIO.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) != 2 { 11 | fmt.Println("Please provide a filename") 12 | os.Exit(1) 13 | } 14 | 15 | filename := os.Args[1] 16 | f, err := os.Open(filename) 17 | if err != nil { 18 | fmt.Printf("error opening %s: %s", filename, err) 19 | os.Exit(1) 20 | } 21 | defer f.Close() 22 | 23 | scanner := bufio.NewScanner(f) 24 | for scanner.Scan() { 25 | line := scanner.Text() 26 | 27 | if scanner.Err() != nil { 28 | fmt.Printf("error reading file %s", err) 29 | os.Exit(1) 30 | } 31 | fmt.Println(line) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter06/byteSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) != 2 { 11 | fmt.Println("Please provide a filename") 12 | os.Exit(1) 13 | } 14 | filename := os.Args[1] 15 | 16 | aByteSlice := []byte("Mihalis Tsoukalos!\n") 17 | ioutil.WriteFile(filename, aByteSlice, 0644) 18 | 19 | f, err := os.Open(filename) 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(1) 23 | } 24 | defer f.Close() 25 | 26 | anotherByteSlice := make([]byte, 100) 27 | n, err := f.Read(anotherByteSlice) 28 | fmt.Printf("Read %d bytes: %s", n, anotherByteSlice) 29 | } 30 | -------------------------------------------------------------------------------- /Chapter06/charByChar.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Not enough arguments!") 15 | os.Exit(1) 16 | } 17 | input := arguments[1] 18 | 19 | buf, err := ioutil.ReadFile(input) 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(1) 23 | } 24 | 25 | in := string(buf) 26 | s := bufio.NewScanner(strings.NewReader(in)) 27 | s.Split(bufio.ScanRunes) 28 | 29 | for s.Scan() { 30 | fmt.Print(s.Text()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter06/cp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | "strconv" 9 | ) 10 | 11 | var BUFFERSIZE int64 12 | 13 | func Copy(src, dst string, BUFFERSIZE int64) error { 14 | sourceFileStat, err := os.Stat(src) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | if !sourceFileStat.Mode().IsRegular() { 20 | return fmt.Errorf("%s is not a regular file.", src) 21 | } 22 | 23 | source, err := os.Open(src) 24 | if err != nil { 25 | return err 26 | } 27 | defer source.Close() 28 | 29 | _, err = os.Stat(dst) 30 | if err == nil { 31 | return fmt.Errorf("File %s already exists.", dst) 32 | } 33 | 34 | destination, err := os.Create(dst) 35 | if err != nil { 36 | return err 37 | } 38 | defer destination.Close() 39 | 40 | if err != nil { 41 | panic(err) 42 | } 43 | 44 | buf := make([]byte, BUFFERSIZE) 45 | for { 46 | n, err := source.Read(buf) 47 | if err != nil && err != io.EOF { 48 | return err 49 | } 50 | if n == 0 { 51 | break 52 | } 53 | 54 | if _, err := destination.Write(buf[:n]); err != nil { 55 | return err 56 | } 57 | } 58 | return err 59 | } 60 | 61 | func main() { 62 | if len(os.Args) != 4 { 63 | fmt.Printf("usage: %s source destination BUFFERSIZE\n", filepath.Base(os.Args[0])) 64 | os.Exit(1) 65 | } 66 | 67 | source := os.Args[1] 68 | destination := os.Args[2] 69 | BUFFERSIZE, _ = strconv.ParseInt(os.Args[3], 10, 64) 70 | 71 | fmt.Printf("Copying %s to %s\n", source, destination) 72 | err := Copy(source, destination, BUFFERSIZE) 73 | if err != nil { 74 | fmt.Printf("File copying failed: %q\n", err) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Chapter06/ddGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "math/rand" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func createBytes(buf *[]byte, count int) { 16 | if count == 0 { 17 | return 18 | } 19 | for i := 0; i < count; i++ { 20 | intByte := byte(random(0, 9)) 21 | *buf = append(*buf, intByte) 22 | } 23 | } 24 | 25 | func main() { 26 | minusBS := flag.Int("bs", 0, "Block Size") 27 | minusCOUNT := flag.Int("count", 0, "Counter") 28 | flag.Parse() 29 | flags := flag.Args() 30 | 31 | if len(flags) == 0 { 32 | fmt.Println("Not enough arguments!") 33 | os.Exit(-1) 34 | } 35 | 36 | if *minusBS < 0 || *minusCOUNT < 0 { 37 | fmt.Println("Count or/and Byte Size < 0!") 38 | os.Exit(-1) 39 | } 40 | 41 | filename := flags[0] 42 | rand.Seed(time.Now().Unix()) 43 | 44 | _, err := os.Stat(filename) 45 | if err == nil { 46 | fmt.Printf("File %s already exists.\n", filename) 47 | os.Exit(1) 48 | } 49 | 50 | destination, err := os.Create(filename) 51 | if err != nil { 52 | fmt.Println("os.Create:", err) 53 | os.Exit(1) 54 | } 55 | 56 | buf := make([]byte, *minusBS) 57 | buf = nil 58 | for i := 0; i < *minusCOUNT; i++ { 59 | createBytes(&buf, *minusBS) 60 | if _, err := destination.Write(buf); err != nil { 61 | fmt.Println(err) 62 | os.Exit(-1) 63 | } 64 | buf = nil 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Chapter06/fileLocking.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | var mu sync.Mutex 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func writeDataToFile(i int, file *os.File, w *sync.WaitGroup) { 18 | mu.Lock() 19 | time.Sleep(time.Duration(random(10, 1000)) * time.Millisecond) 20 | fmt.Fprintf(file, "From %d, writing %d\n", i, 2*i) 21 | fmt.Printf("Wrote from %d\n", i) 22 | w.Done() 23 | } 24 | 25 | func main() { 26 | if len(os.Args) != 2 { 27 | fmt.Println("Please provide one command line argument!") 28 | os.Exit(-1) 29 | } 30 | 31 | filename := os.Args[1] 32 | number := 3 33 | 34 | file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) 35 | if err != nil { 36 | fmt.Println(err) 37 | os.Exit(1) 38 | } 39 | 40 | var w *sync.WaitGroup = new(sync.WaitGroup) 41 | w.Add(number) 42 | 43 | for r := 0; r < number; r++ { 44 | go writeDataToFile(r, file, w) 45 | } 46 | 47 | w.Wait() 48 | } 49 | -------------------------------------------------------------------------------- /Chapter06/fmtF.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | if len(os.Args) != 2 { 10 | fmt.Println("Please provide a filename") 11 | os.Exit(1) 12 | } 13 | 14 | filename := os.Args[1] 15 | destination, err := os.Create(filename) 16 | if err != nil { 17 | fmt.Println("os.Create:", err) 18 | os.Exit(1) 19 | } 20 | defer destination.Close() 21 | 22 | fmt.Fprintf(destination, "[%s]: ", filename) 23 | fmt.Fprintf(destination, "Using fmt.Fprintf in %s\n", filename) 24 | } 25 | -------------------------------------------------------------------------------- /Chapter06/notGoodCP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func Copy(src, dst string) (int64, error) { 10 | 11 | sourceFileStat, err := os.Stat(src) 12 | if err != nil { 13 | return 0, err 14 | } 15 | 16 | if !sourceFileStat.Mode().IsRegular() { 17 | return 0, fmt.Errorf("%s is not a regular file", src) 18 | } 19 | 20 | source, err := os.Open(src) 21 | if err != nil { 22 | return 0, err 23 | } 24 | defer source.Close() 25 | 26 | destination, err := os.Create(dst) 27 | if err != nil { 28 | return 0, err 29 | } 30 | defer destination.Close() 31 | nBytes, err := io.Copy(destination, source) 32 | return nBytes, err 33 | 34 | } 35 | 36 | func main() { 37 | if len(os.Args) != 3 { 38 | fmt.Println("Please provide two command line arguments!") 39 | os.Exit(1) 40 | } 41 | 42 | sourceFile := os.Args[1] 43 | destinationFile := os.Args[2] 44 | nBytes, err := Copy(sourceFile, destinationFile) 45 | 46 | if err != nil { 47 | fmt.Printf("The copy operation failed %q\n", err) 48 | } else { 49 | fmt.Printf("Copied %d bytes!\n", nBytes) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter06/readAll.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) != 3 { 11 | fmt.Println("Please provide two command line arguments!") 12 | os.Exit(1) 13 | } 14 | 15 | sourceFile := os.Args[1] 16 | destinationFile := os.Args[2] 17 | 18 | input, err := ioutil.ReadFile(sourceFile) 19 | if err != nil { 20 | fmt.Println(err) 21 | os.Exit(1) 22 | } 23 | 24 | err = ioutil.WriteFile(destinationFile, input, 0644) 25 | if err != nil { 26 | fmt.Println("Error creating the new file", destinationFile) 27 | fmt.Println(err) 28 | os.Exit(1) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter06/readBinary.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | "fmt" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Println("Please provide an integer") 14 | os.Exit(1) 15 | } 16 | aNumber, _ := strconv.ParseInt(os.Args[1], 10, 64) 17 | 18 | buf := new(bytes.Buffer) 19 | err := binary.Write(buf, binary.LittleEndian, aNumber) 20 | if err != nil { 21 | fmt.Println("Little Endian:", err) 22 | } 23 | 24 | fmt.Printf("%d is %x in Little Endian\n", aNumber, buf) 25 | 26 | err = binary.Write(buf, binary.BigEndian, aNumber) 27 | if err != nil { 28 | fmt.Println("Big Endian:", err) 29 | } 30 | fmt.Printf("And %x in Big Endian\n", buf) 31 | } 32 | -------------------------------------------------------------------------------- /Chapter06/readColumn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | minusCOL := flag.Int("COL", 1, "Column") 14 | flag.Parse() 15 | flags := flag.Args() 16 | 17 | if len(flags) == 0 { 18 | fmt.Printf("usage: readColumn [ [... = column { 50 | fmt.Println((data[column-1])) 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Chapter06/readerWriter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func countChars(r io.Reader) int { 10 | buf := make([]byte, 16) 11 | total := 0 12 | for { 13 | n, err := r.Read(buf) 14 | if err != nil && err != io.EOF { 15 | return 0 16 | } 17 | if err == io.EOF { 18 | break 19 | } 20 | total = total + n 21 | } 22 | return total 23 | } 24 | 25 | func writeNumberOfChars(w io.Writer, x int) { 26 | fmt.Fprintf(w, "%d\n", x) 27 | } 28 | 29 | func main() { 30 | if len(os.Args) != 2 { 31 | fmt.Println("Please provide a filename") 32 | os.Exit(1) 33 | } 34 | 35 | filename := os.Args[1] 36 | _, err := os.Stat(filename) 37 | if err != nil { 38 | fmt.Printf("Error opening %s.\n", filename) 39 | os.Exit(1) 40 | } 41 | 42 | f, err := os.Open(filename) 43 | if err != nil { 44 | fmt.Println("Cannot open file:", err) 45 | os.Exit(-1) 46 | } 47 | defer f.Close() 48 | 49 | chars := countChars(f) 50 | filename = filename + ".Count" 51 | f, err = os.Create(filename) 52 | if err != nil { 53 | fmt.Println("os.Create:", err) 54 | os.Exit(1) 55 | } 56 | defer f.Close() 57 | writeNumberOfChars(f, chars) 58 | } 59 | -------------------------------------------------------------------------------- /Chapter06/records.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) != 2 { 11 | fmt.Println("Need just one filename!") 12 | os.Exit(-1) 13 | } 14 | 15 | filename := os.Args[1] 16 | _, err := os.Stat(filename) 17 | if err == nil { 18 | fmt.Printf("File %s already exists.\n", filename) 19 | os.Exit(1) 20 | } 21 | 22 | output, err := os.Create(filename) 23 | if err != nil { 24 | fmt.Println(err) 25 | os.Exit(-1) 26 | } 27 | defer output.Close() 28 | 29 | inputData := [][]string{{"M", "T", "I."}, {"D", "T", "I."}, {"M", "T", "D."}, {"V", "T", "D."}, {"A", "T", "D."}} 30 | writer := csv.NewWriter(output) 31 | for _, record := range inputData { 32 | err := writer.Write(record) 33 | if err != nil { 34 | fmt.Println(err) 35 | os.Exit(-1) 36 | } 37 | } 38 | writer.Flush() 39 | 40 | f, err := os.Open(filename) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | defer f.Close() 46 | 47 | reader := csv.NewReader(f) 48 | reader.FieldsPerRecord = -1 49 | allRecords, err := reader.ReadAll() 50 | if err != nil { 51 | fmt.Println(err) 52 | os.Exit(1) 53 | } 54 | 55 | for _, rec := range allRecords { 56 | fmt.Printf("%s:%s:%s\n", rec[0], rec[1], rec[2]) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Chapter06/sparse.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "path/filepath" 8 | "strconv" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 3 { 13 | fmt.Printf("usage: %s SIZE filename\n", filepath.Base(os.Args[0])) 14 | os.Exit(1) 15 | } 16 | 17 | SIZE, _ := strconv.ParseInt(os.Args[1], 10, 64) 18 | filename := os.Args[2] 19 | 20 | _, err := os.Stat(filename) 21 | if err == nil { 22 | fmt.Printf("File %s already exists.\n", filename) 23 | os.Exit(1) 24 | } 25 | 26 | fd, err := os.Create(filename) 27 | if err != nil { 28 | log.Fatal("Failed to create output") 29 | } 30 | 31 | _, err = fd.Seek(SIZE-1, 0) 32 | if err != nil { 33 | fmt.Println(err) 34 | log.Fatal("Failed to seek") 35 | } 36 | 37 | _, err = fd.Write([]byte{0}) 38 | if err != nil { 39 | fmt.Println(err) 40 | log.Fatal("Write operation failed") 41 | } 42 | 43 | err = fd.Close() 44 | if err != nil { 45 | fmt.Println(err) 46 | log.Fatal("Failed to close file") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chapter06/tabSpace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "path/filepath" 7 | "bufio" 8 | "io" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | if len(os.Args) != 3 { 14 | fmt.Printf("Usage: %s [-t|-s] filename!\n", filepath.Base(os.Args[0])) 15 | os.Exit(1) 16 | } 17 | 18 | option := os.Args[1] 19 | filename := os.Args[2] 20 | if option != "-t" && option != "-s" { 21 | fmt.Println("Unknown option!") 22 | os.Exit(1) 23 | } 24 | 25 | f, err := os.Open(filename) 26 | if err != nil { 27 | fmt.Printf("error opening %s: %s", filename, err) 28 | os.Exit(1) 29 | } 30 | defer f.Close() 31 | 32 | r := bufio.NewReader(f) 33 | for { 34 | line, err := r.ReadString('\n') 35 | 36 | if err == io.EOF { 37 | outputNewLine(option, line) 38 | break 39 | } else if err != nil { 40 | fmt.Printf("error reading file %s", err) 41 | os.Exit(1) 42 | } 43 | 44 | outputNewLine(option,line) 45 | } 46 | } 47 | 48 | func outputNewLine(option, line string) { 49 | if option == "-t" { 50 | fmt.Print(strings.Replace(line, "\t", " ", -1)) 51 | }else { 52 | fmt.Print(strings.Replace(line, " ", "\t", -1)) 53 | } 54 | } -------------------------------------------------------------------------------- /Chapter06/usingIO.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) != 2 { 11 | fmt.Println("Please provide a filename") 12 | os.Exit(1) 13 | } 14 | 15 | filename := os.Args[1] 16 | f, err := os.Open(filename) 17 | if err != nil { 18 | fmt.Printf("error opening %s: %s", filename, err) 19 | os.Exit(1) 20 | } 21 | defer f.Close() 22 | 23 | buf := make([]byte, 8) 24 | if _, err := io.ReadFull(f, buf); err != nil { 25 | if err == io.EOF { 26 | err = io.ErrUnexpectedEOF 27 | } 28 | } 29 | io.WriteString(os.Stdout, string(buf)) 30 | fmt.Println() 31 | } 32 | -------------------------------------------------------------------------------- /Chapter06/wc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "regexp" 10 | ) 11 | 12 | func countLines(filename string) (int, int, int) { 13 | var err error 14 | var numberOfLines int 15 | var numberOfCharacters int 16 | var numberOfWords int 17 | numberOfLines = 0 18 | numberOfCharacters = 0 19 | numberOfWords = 0 20 | 21 | f, err := os.Open(filename) 22 | if err != nil { 23 | fmt.Printf("error opening file %s", err) 24 | os.Exit(1) 25 | } 26 | defer f.Close() 27 | 28 | r := bufio.NewReader(f) 29 | for { 30 | line, err := r.ReadString('\n') 31 | 32 | if err == io.EOF { 33 | numberOfCharacters += len(line) 34 | r := regexp.MustCompile("[^\\s]+") 35 | numberOfWords += len(r.FindAllString(line, -1)) 36 | break 37 | } else if err != nil { 38 | fmt.Printf("error reading file %s", err) 39 | } 40 | 41 | numberOfLines++ 42 | r := regexp.MustCompile("[^\\s]+") 43 | for range r.FindAllString(line, -1) { 44 | numberOfWords++ 45 | } 46 | numberOfCharacters += len(line) 47 | } 48 | 49 | return numberOfLines, numberOfWords, numberOfCharacters 50 | } 51 | 52 | func main() { 53 | minusC := flag.Bool("c", false, "Characters") 54 | minusW := flag.Bool("w", false, "Words") 55 | minusL := flag.Bool("l", false, "Lines") 56 | 57 | flag.Parse() 58 | flags := flag.Args() 59 | 60 | if len(flags) == 0 { 61 | fmt.Printf("usage: wc [ [... [ [... \n", filepath.Base(arguments[0])) 14 | os.Exit(1) 15 | } 16 | 17 | for _, filename := range arguments[1:] { 18 | fileInfo, err := os.Stat(filename) 19 | if err != nil { 20 | fmt.Println(err) 21 | continue 22 | } 23 | 24 | fmt.Printf("%+v\n", fileInfo.Sys()) 25 | fmt.Println(fileInfo.Sys().(*syscall.Stat_t).Uid) 26 | fmt.Println(fileInfo.Sys().(*syscall.Stat_t).Gid) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter07/findPerm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | var PERMISSIONS string 10 | 11 | func permissionsOfFIle(filename string) string { 12 | info, err := os.Stat(filename) 13 | if err != nil { 14 | return "-1" 15 | } 16 | mode := info.Mode() 17 | return mode.String()[1:10] 18 | } 19 | 20 | func walkFunction(path string, info os.FileInfo, err error) error { 21 | _, err = os.Lstat(path) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | if permissionsOfFIle(path) == PERMISSIONS { 27 | fmt.Println(path) 28 | } 29 | return err 30 | } 31 | 32 | func main() { 33 | arguments := os.Args 34 | if len(arguments) != 3 { 35 | fmt.Printf("usage: %s RootDirectory permissions\n", filepath.Base(arguments[0])) 36 | os.Exit(1) 37 | } 38 | 39 | Path := arguments[1] 40 | Path, _ = filepath.EvalSymlinks(Path) 41 | PERMISSIONS = arguments[2] 42 | 43 | err := filepath.Walk(Path, walkFunction) 44 | if err != nil { 45 | fmt.Println(err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chapter07/goodPass.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "math/rand" 7 | "os" 8 | "path/filepath" 9 | "strconv" 10 | ) 11 | 12 | var MAX int = 90 13 | var MIN int = 0 14 | var seedSize int = 10 15 | 16 | func random(min, max int) int { 17 | return rand.Intn(max-min) + min 18 | } 19 | 20 | func main() { 21 | if len(os.Args) != 2 { 22 | fmt.Printf("usage: %s length\n", filepath.Base(os.Args[0])) 23 | os.Exit(1) 24 | } 25 | 26 | LENGTH, _ := strconv.ParseInt(os.Args[1], 10, 64) 27 | f, _ := os.Open("/dev/random") 28 | var seed int64 29 | binary.Read(f, binary.LittleEndian, &seed) 30 | rand.Seed(seed) 31 | f.Close() 32 | fmt.Println("Seed:", seed) 33 | 34 | startChar := "!" 35 | var i int64 36 | for i = 0; i < LENGTH; i++ { 37 | anInt := int(random(MIN, MAX)) 38 | newChar := string(startChar[0] + byte(anInt)) 39 | if newChar == " " { 40 | i = i - i 41 | continue 42 | } 43 | fmt.Print(newChar) 44 | } 45 | fmt.Println() 46 | } 47 | -------------------------------------------------------------------------------- /Chapter07/insertLineNumber.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | minusINIT := flag.Int("init", 1, "Initial Value") 13 | flag.Parse() 14 | flags := flag.Args() 15 | 16 | if len(flags) == 0 { 17 | fmt.Printf("usage: insertLineNumber [ [... ENTRIESPERLOGFILE { 46 | _ = rotateLogFile(filename) 47 | numberOfLogEntries = 0 48 | } 49 | if TOTALWRITES > WHENTOSTOP { 50 | _ = rotateLogFile(filename) 51 | break 52 | } 53 | time.Sleep(time.Second) 54 | } 55 | fmt.Println("Wrote", TOTALWRITES, "log entries!") 56 | } 57 | -------------------------------------------------------------------------------- /Chapter07/setFilePerm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strconv" 8 | ) 9 | 10 | func tripletToBinary(triplet string) string { 11 | if triplet == "rwx" { 12 | return "111" 13 | } 14 | if triplet == "-wx" { 15 | return "011" 16 | } 17 | if triplet == "--x" { 18 | return "001" 19 | } 20 | if triplet == "---" { 21 | return "000" 22 | } 23 | if triplet == "r-x" { 24 | return "101" 25 | } 26 | if triplet == "r--" { 27 | return "100" 28 | } 29 | if triplet == "--x" { 30 | return "001" 31 | } 32 | if triplet == "rw-" { 33 | return "110" 34 | } 35 | if triplet == "-w-" { 36 | return "010" 37 | } 38 | return "unknown" 39 | } 40 | 41 | func convertToBinary(permissions string) string { 42 | p1 := permissions[0:3] 43 | p2 := permissions[3:6] 44 | p3 := permissions[6:9] 45 | 46 | p1 = tripletToBinary(p1) 47 | p2 = tripletToBinary(p2) 48 | p3 = tripletToBinary(p3) 49 | 50 | p1Int, _ := strconv.ParseInt(p1, 2, 64) 51 | p2Int, _ := strconv.ParseInt(p2, 2, 64) 52 | p3Int, _ := strconv.ParseInt(p3, 2, 64) 53 | 54 | returnValue := p1Int*100 + p2Int*10 + p3Int 55 | tempReturnValue := int(returnValue) 56 | returnString := "0" + strconv.Itoa(tempReturnValue) 57 | return returnString 58 | } 59 | 60 | func main() { 61 | arguments := os.Args 62 | if len(arguments) != 3 { 63 | fmt.Printf("usage: %s filename permissions\n", filepath.Base(arguments[0])) 64 | os.Exit(1) 65 | } 66 | 67 | filename, _ := filepath.EvalSymlinks(arguments[1]) 68 | permissions := arguments[2] 69 | if len(permissions) != 9 { 70 | fmt.Println("Permissions should be 9 characters (rwxrwxrwx):", permissions) 71 | os.Exit(-1) 72 | } 73 | 74 | bin := convertToBinary(permissions) 75 | newPerms, _ := strconv.ParseUint(bin, 0, 32) 76 | newMode := os.FileMode(newPerms) 77 | os.Chmod(filename, newMode) 78 | } 79 | -------------------------------------------------------------------------------- /Chapter07/swapRE.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "regexp" 10 | ) 11 | 12 | func main() { 13 | flag.Parse() 14 | if flag.NArg() != 1 { 15 | fmt.Println("Please provide one log file to process!") 16 | os.Exit(-1) 17 | } 18 | numberOfLines := 0 19 | numberOfLinesMatched := 0 20 | 21 | filename := flag.Arg(0) 22 | f, err := os.Open(filename) 23 | if err != nil { 24 | fmt.Printf("error opening file %s", err) 25 | os.Exit(1) 26 | } 27 | defer f.Close() 28 | 29 | r := bufio.NewReader(f) 30 | for { 31 | line, err := r.ReadString('\n') 32 | if err == io.EOF { 33 | break 34 | } else if err != nil { 35 | fmt.Printf("error reading file %s", err) 36 | } 37 | 38 | numberOfLines++ 39 | r := regexp.MustCompile(`(.*) (\[\d\d\/(\w+)/\d\d\d\d:\d\d:\d\d:\d\d(.*)\]) (.*) (\d+)`) 40 | if r.MatchString(line) { 41 | numberOfLinesMatched++ 42 | match := r.FindStringSubmatch(line) 43 | fmt.Println(match[1], match[6], match[5], match[2]) 44 | } 45 | } 46 | fmt.Println("Line processed:", numberOfLines) 47 | fmt.Println("Line matched:", numberOfLinesMatched) 48 | } 49 | -------------------------------------------------------------------------------- /Chapter07/useSyslog.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | 13 | programName := filepath.Base(os.Args[0]) 14 | sysLog, e := syslog.New(syslog.LOG_INFO|syslog.LOG_LOCAL7, programName) 15 | if e != nil { 16 | log.Fatal(e) 17 | } 18 | sysLog.Crit("Crit: Logging in Go!") 19 | 20 | sysLog, e = syslog.New(syslog.LOG_ALERT|syslog.LOG_LOCAL7, "Some program!") 21 | if e != nil { 22 | log.Fatal(sysLog) 23 | } 24 | sysLog.Emerg("Emerg: Logging in Go!") 25 | 26 | fmt.Fprintf(sysLog, "log.Print: Logging in Go!") 27 | } 28 | -------------------------------------------------------------------------------- /Chapter07/userFiles.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "os/user" 8 | "path/filepath" 9 | "strconv" 10 | "syscall" 11 | ) 12 | 13 | var uid int32 = 0 14 | var INCLUDE bool = true 15 | 16 | func userOfFIle(filename string) int32 { 17 | fileInfo, err := os.Stat(filename) 18 | if err != nil { 19 | fmt.Println(err) 20 | return 1000000 21 | } 22 | UID := fileInfo.Sys().(*syscall.Stat_t).Uid 23 | return int32(UID) 24 | } 25 | 26 | func walkFunction(path string, info os.FileInfo, err error) error { 27 | _, err = os.Lstat(path) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | if userOfFIle(path) == uid && INCLUDE { 33 | fmt.Println(path) 34 | } else if userOfFIle(path) != uid && !(INCLUDE) { 35 | fmt.Println(path) 36 | } 37 | return err 38 | } 39 | 40 | func main() { 41 | minusNO := flag.Bool("no", true, "Include") 42 | minusPATH := flag.String("path", ".", "Path to Search") 43 | flag.Parse() 44 | flags := flag.Args() 45 | 46 | INCLUDE = *minusNO 47 | Path := *minusPATH 48 | 49 | if len(flags) == 0 { 50 | uid = int32(os.Getuid()) 51 | } else { 52 | u, err := user.Lookup(flags[0]) 53 | if err != nil { 54 | fmt.Println(err) 55 | os.Exit(1) 56 | } 57 | temp, err := strconv.ParseInt(u.Uid, 10, 32) 58 | uid = int32(temp) 59 | } 60 | 61 | err := filepath.Walk(Path, walkFunction) 62 | if err != nil { 63 | fmt.Println(err) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Chapter07/userID.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/user" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | uid := os.Getuid() 13 | fmt.Println(uid) 14 | return 15 | } 16 | 17 | username := arguments[1] 18 | u, err := user.Lookup(username) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(u.Uid) 24 | } 25 | -------------------------------------------------------------------------------- /Chapter08/UNIXshell.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | var VERSION string = "0.2" 11 | 12 | func main() { 13 | scanner := bufio.NewScanner(os.Stdin) 14 | fmt.Print("> ") 15 | for scanner.Scan() { 16 | 17 | line := scanner.Text() 18 | words := strings.Split(line, " ") 19 | command := words[0] 20 | 21 | switch command { 22 | case "exit": 23 | fmt.Println("Exiting...") 24 | os.Exit(0) 25 | case "version": 26 | fmt.Println(VERSION) 27 | default: 28 | fmt.Println(line) 29 | } 30 | 31 | fmt.Print("> ") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08/catchAll.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handleSignal(signal os.Signal) { 12 | fmt.Println("* Got:", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | switch sig { 22 | case os.Interrupt: 23 | handleSignal(sig) 24 | case syscall.SIGTERM: 25 | handleSignal(sig) 26 | os.Exit(-1) 27 | case syscall.SIGUSR1: 28 | handleSignal(sig) 29 | default: 30 | fmt.Println("Ignoring:", sig) 31 | } 32 | } 33 | }() 34 | 35 | for { 36 | fmt.Printf(".") 37 | time.Sleep(10 * time.Second) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chapter08/cpSignal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "os/signal" 8 | "path/filepath" 9 | "strconv" 10 | "syscall" 11 | ) 12 | 13 | var BUFFERSIZE int64 14 | var FILESIZE int64 15 | var BYTESWRITTEN int64 16 | 17 | func Copy(src, dst string, BUFFERSIZE int64) error { 18 | sourceFileStat, err := os.Stat(src) 19 | if err != nil { 20 | return err 21 | } 22 | 23 | FILESIZE = sourceFileStat.Size() 24 | 25 | if !sourceFileStat.Mode().IsRegular() { 26 | return fmt.Errorf("%s is not a regular file.", src) 27 | } 28 | 29 | source, err := os.Open(src) 30 | if err != nil { 31 | return err 32 | } 33 | defer source.Close() 34 | 35 | _, err = os.Stat(dst) 36 | if err == nil { 37 | return fmt.Errorf("File %s already exists.", dst) 38 | } 39 | 40 | destination, err := os.Create(dst) 41 | if err != nil { 42 | return err 43 | } 44 | defer destination.Close() 45 | 46 | if err != nil { 47 | panic(err) 48 | } 49 | 50 | buf := make([]byte, BUFFERSIZE) 51 | for { 52 | n, err := source.Read(buf) 53 | if err != nil && err != io.EOF { 54 | return err 55 | } 56 | if n == 0 { 57 | break 58 | } 59 | if _, err := destination.Write(buf[:n]); err != nil { 60 | return err 61 | } 62 | BYTESWRITTEN = BYTESWRITTEN + int64(n) 63 | } 64 | return err 65 | } 66 | 67 | func progressInfo() { 68 | progress := float64(BYTESWRITTEN) / float64(FILESIZE) * 100 69 | fmt.Printf("Progress: %.2f%%\n", progress) 70 | } 71 | 72 | func main() { 73 | if len(os.Args) != 4 { 74 | fmt.Printf("usage: %s source destination BUFFERSIZE\n", filepath.Base(os.Args[0])) 75 | os.Exit(1) 76 | } 77 | 78 | source := os.Args[1] 79 | destination := os.Args[2] 80 | BUFFERSIZE, _ = strconv.ParseInt(os.Args[3], 10, 64) 81 | BYTESWRITTEN = 0 82 | 83 | sigs := make(chan os.Signal, 1) 84 | signal.Notify(sigs) 85 | go func() { 86 | for { 87 | sig := <-sigs 88 | switch sig { 89 | case syscall.SIGINFO: 90 | progressInfo() 91 | default: 92 | fmt.Println("Ignored:", sig) 93 | } 94 | } 95 | }() 96 | 97 | fmt.Printf("Copying %s to %s\n", source, destination) 98 | err := Copy(source, destination, BUFFERSIZE) 99 | if err != nil { 100 | fmt.Printf("File copying failed: %q\n", err) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Chapter08/extractData.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "path/filepath" 9 | "regexp" 10 | "strconv" 11 | ) 12 | 13 | func findIP(input string) string { 14 | partIP := "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" 15 | grammar := partIP + "\\." + partIP + "\\." + partIP + "\\." + partIP 16 | matchMe := regexp.MustCompile(grammar) 17 | return matchMe.FindString(input) 18 | } 19 | 20 | func main() { 21 | arguments := os.Args 22 | if len(arguments) < 3 { 23 | fmt.Printf("%s IP \n", filepath.Base(os.Args[0])) 24 | os.Exit(-1) 25 | } 26 | 27 | WANTED := arguments[1] 28 | for _, filename := range arguments[2:] { 29 | count := 0 30 | buf := []byte(filename) 31 | io.WriteString(os.Stdout, string(buf)) 32 | f, err := os.Open(filename) 33 | if err != nil { 34 | fmt.Fprintf(os.Stderr, "Error: %s\n", err) 35 | continue 36 | } 37 | defer f.Close() 38 | 39 | r := bufio.NewReader(f) 40 | for { 41 | line, err := r.ReadString('\n') 42 | if err == io.EOF { 43 | break 44 | } else if err != nil { 45 | fmt.Fprintf(os.Stderr, "Error in file: %s\n", err) 46 | continue 47 | } 48 | 49 | ip := findIP(line) 50 | if ip == WANTED { 51 | count = count + 1 52 | } 53 | } 54 | buf = []byte(strconv.Itoa(count)) 55 | io.WriteString(os.Stdout, " ") 56 | io.WriteString(os.Stdout, string(buf)) 57 | io.WriteString(os.Stdout, "\n") 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter08/h1s.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handleSignal(signal os.Signal) { 12 | fmt.Println("Got", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | fmt.Println(sig) 22 | handleSignal(sig) 23 | } 24 | }() 25 | 26 | for { 27 | fmt.Printf(".") 28 | time.Sleep(10 * time.Second) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter08/listProcess.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "syscall" 8 | ) 9 | 10 | func main() { 11 | 12 | PS, err := exec.LookPath("ps") 13 | if err != nil { 14 | fmt.Println(err) 15 | } 16 | fmt.Println(PS) 17 | 18 | command := []string{"ps", "-a", "-x"} 19 | env := os.Environ() 20 | err = syscall.Exec(PS, command, env) 21 | if err != nil { 22 | fmt.Println(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter08/plotData.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "image" 7 | "image/color" 8 | "image/png" 9 | "os" 10 | "path/filepath" 11 | "strconv" 12 | ) 13 | 14 | var m *image.NRGBA 15 | var x int 16 | var y int 17 | var barWidth int 18 | 19 | func plotBar(width int, height int, color color.RGBA) { 20 | xx := 0 21 | for xx < barWidth { 22 | yy := 0 23 | for yy < height { 24 | m.Set(xx+width, y-yy, color) 25 | yy = yy + 1 26 | } 27 | xx = xx + 1 28 | } 29 | } 30 | 31 | func getColor(x int) color.RGBA { 32 | switch { 33 | case x == 0: 34 | return color.RGBA{0, 0, 255, 255} 35 | case x == 1: 36 | return color.RGBA{255, 0, 0, 255} 37 | case x == 2: 38 | return color.RGBA{0, 255, 0, 255} 39 | case x == 3: 40 | return color.RGBA{255, 255, 0, 255} 41 | case x == 4: 42 | return color.RGBA{255, 0, 255, 255} 43 | case x == 5: 44 | return color.RGBA{0, 255, 255, 255} 45 | case x == 6: 46 | return color.RGBA{255, 100, 100, 255} 47 | case x == 7: 48 | return color.RGBA{100, 100, 255, 255} 49 | case x == 8: 50 | return color.RGBA{100, 255, 255, 255} 51 | case x == 9: 52 | return color.RGBA{255, 255, 255, 255} 53 | } 54 | return color.RGBA{0, 0, 0, 255} 55 | } 56 | 57 | func main() { 58 | var data []int 59 | var f *os.File 60 | arguments := os.Args 61 | if len(arguments) < 3 { 62 | fmt.Printf("%s X Y input\n", filepath.Base(arguments[0])) 63 | os.Exit(0) 64 | } 65 | 66 | if len(arguments) == 3 { 67 | f = os.Stdin 68 | } else { 69 | filename := arguments[3] 70 | fTemp, err := os.Open(filename) 71 | if err != nil { 72 | fmt.Println(err) 73 | os.Exit(0) 74 | } 75 | f = fTemp 76 | } 77 | defer f.Close() 78 | 79 | x, _ = strconv.Atoi(arguments[1]) 80 | y, _ = strconv.Atoi(arguments[2]) 81 | fmt.Println("Image size:", x, y) 82 | 83 | scanner := bufio.NewScanner(f) 84 | for scanner.Scan() { 85 | value, err := strconv.Atoi(scanner.Text()) 86 | if err == nil { 87 | data = append(data, value) 88 | } else { 89 | fmt.Println("Error:", value) 90 | } 91 | } 92 | 93 | fmt.Println("Slice length:", len(data)) 94 | if len(data)*2 > x { 95 | fmt.Println("Image size (x) too small!") 96 | os.Exit(-1) 97 | } 98 | 99 | maxValue := data[0] 100 | for _, temp := range data { 101 | if maxValue < temp { 102 | maxValue = temp 103 | } 104 | } 105 | 106 | if maxValue > y { 107 | fmt.Println("Image size (y) too small!") 108 | os.Exit(-1) 109 | } 110 | fmt.Println("maxValue:", maxValue) 111 | barHeighPerUnit := int(y / maxValue) 112 | fmt.Println("barHeighPerUnit:", barHeighPerUnit) 113 | 114 | PNGfile := arguments[1] + "x" + arguments[2] + ".png" 115 | OUTPUT, err := os.OpenFile(PNGfile, os.O_CREATE|os.O_WRONLY, 0644) 116 | if err != nil { 117 | fmt.Println(err) 118 | os.Exit(-1) 119 | } 120 | m = image.NewNRGBA(image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{x, y}}) 121 | 122 | i := 0 123 | barWidth = int(x / len(data)) 124 | fmt.Println("barWidth:", barWidth) 125 | for _, v := range data { 126 | c := getColor(v % 10) 127 | yy := v * barHeighPerUnit 128 | plotBar(barWidth*i, yy, c) 129 | fmt.Println("plotBar", barWidth*i, yy) 130 | i = i + 1 131 | } 132 | 133 | png.Encode(OUTPUT, m) 134 | } 135 | -------------------------------------------------------------------------------- /Chapter08/plotIP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "image" 7 | "image/color" 8 | "image/png" 9 | "io" 10 | "os" 11 | "path/filepath" 12 | "regexp" 13 | "strconv" 14 | ) 15 | 16 | var m *image.NRGBA 17 | var x int 18 | var y int 19 | var barWidth int 20 | 21 | func findIP(input string) string { 22 | partIP := "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" 23 | grammar := partIP + "\\." + partIP + "\\." + partIP + "\\." + partIP 24 | matchMe := regexp.MustCompile(grammar) 25 | return matchMe.FindString(input) 26 | } 27 | 28 | func plotBar(width int, height int, color color.RGBA) { 29 | xx := 0 30 | for xx < barWidth { 31 | yy := 0 32 | for yy < height { 33 | m.Set(xx+width, y-yy, color) 34 | yy = yy + 1 35 | } 36 | xx = xx + 1 37 | } 38 | } 39 | 40 | func getColor(x int) color.RGBA { 41 | switch { 42 | case x == 0: 43 | return color.RGBA{0, 0, 255, 255} 44 | case x == 1: 45 | return color.RGBA{255, 0, 0, 255} 46 | case x == 2: 47 | return color.RGBA{0, 255, 0, 255} 48 | case x == 3: 49 | return color.RGBA{255, 255, 0, 255} 50 | case x == 4: 51 | return color.RGBA{255, 0, 255, 255} 52 | case x == 5: 53 | return color.RGBA{0, 255, 255, 255} 54 | case x == 6: 55 | return color.RGBA{255, 100, 100, 255} 56 | case x == 7: 57 | return color.RGBA{100, 100, 255, 255} 58 | case x == 8: 59 | return color.RGBA{100, 255, 255, 255} 60 | case x == 9: 61 | return color.RGBA{255, 255, 255, 255} 62 | } 63 | return color.RGBA{0, 0, 0, 255} 64 | } 65 | 66 | func main() { 67 | var data []int 68 | arguments := os.Args 69 | if len(arguments) < 4 { 70 | fmt.Printf("%s X Y IP input\n", filepath.Base(arguments[0])) 71 | os.Exit(0) 72 | } 73 | 74 | x, _ = strconv.Atoi(arguments[1]) 75 | y, _ = strconv.Atoi(arguments[2]) 76 | WANTED := arguments[3] 77 | fmt.Println("Image size:", x, y) 78 | 79 | for _, filename := range arguments[4:] { 80 | count := 0 81 | fmt.Println(filename) 82 | f, err := os.Open(filename) 83 | if err != nil { 84 | fmt.Fprintf(os.Stderr, "Error: %s\n", err) 85 | continue 86 | } 87 | defer f.Close() 88 | 89 | r := bufio.NewReader(f) 90 | for { 91 | line, err := r.ReadString('\n') 92 | if err == io.EOF { 93 | break 94 | } else if err != nil { 95 | fmt.Fprintf(os.Stderr, "Error in file: %s\n", err) 96 | continue 97 | } 98 | ip := findIP(line) 99 | if ip == WANTED { 100 | count = count + 1 101 | } 102 | } 103 | data = append(data, count) 104 | } 105 | 106 | fmt.Println("Slice length:", len(data)) 107 | if len(data)*2 > x { 108 | fmt.Println("Image size (x) too small!") 109 | os.Exit(-1) 110 | } 111 | 112 | maxValue := data[0] 113 | for _, temp := range data { 114 | if maxValue < temp { 115 | maxValue = temp 116 | } 117 | } 118 | 119 | if maxValue > y { 120 | fmt.Println("Image size (y) too small!") 121 | os.Exit(-1) 122 | } 123 | fmt.Println("maxValue:", maxValue) 124 | barHeighPerUnit := int(y / maxValue) 125 | fmt.Println("barHeighPerUnit:", barHeighPerUnit) 126 | PNGfile := WANTED + ".png" 127 | OUTPUT, err := os.OpenFile(PNGfile, os.O_CREATE|os.O_WRONLY, 0644) 128 | if err != nil { 129 | fmt.Println(err) 130 | os.Exit(-1) 131 | } 132 | m = image.NewNRGBA(image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{x, y}}) 133 | 134 | i := 0 135 | barWidth = int(x / len(data)) 136 | fmt.Println("barWidth:", barWidth) 137 | for _, v := range data { 138 | c := getColor(v % 10) 139 | yy := v * barHeighPerUnit 140 | plotBar(barWidth*i, yy, c) 141 | fmt.Println("plotBar", barWidth*i, yy) 142 | i = i + 1 143 | } 144 | png.Encode(OUTPUT, m) 145 | } 146 | -------------------------------------------------------------------------------- /Chapter08/readSTDIN.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | filename := "" 11 | var f *os.File 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | f = os.Stdin 15 | } else { 16 | filename = arguments[1] 17 | fileHandler, err := os.Open(filename) 18 | if err != nil { 19 | fmt.Printf("error opening %s: %s", filename, err) 20 | os.Exit(1) 21 | } 22 | f = fileHandler 23 | } 24 | defer f.Close() 25 | 26 | scanner := bufio.NewScanner(f) 27 | for scanner.Scan() { 28 | fmt.Println(scanner.Text()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter08/readUNIX.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func readSocket(r io.Reader) { 12 | buf := make([]byte, 1024) 13 | for { 14 | n, _ := r.Read(buf[:]) 15 | fmt.Print("Read: ", string(buf[0:n])) 16 | } 17 | } 18 | 19 | func main() { 20 | c, _ := net.Dial("unix", "/tmp/aSocket.sock") 21 | defer c.Close() 22 | 23 | go readSocket(c) 24 | n := 0 25 | for { 26 | message := []byte("Hi there: " + strconv.Itoa(n) + "\n") 27 | _, _ = c.Write(message) 28 | time.Sleep(5 * time.Second) 29 | n = n + 1 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter08/rotateSignals.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "strconv" 9 | "syscall" 10 | "time" 11 | ) 12 | 13 | var TOTALWRITES int = 0 14 | var openLogFile os.File 15 | 16 | func rotateLogFile(filename string) error { 17 | openLogFile.Close() 18 | os.Rename(filename, filename+"."+strconv.Itoa(TOTALWRITES)) 19 | err := setUpLogFile(filename) 20 | return err 21 | } 22 | 23 | func setUpLogFile(filename string) error { 24 | openLogFile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) 25 | if err != nil { 26 | return err 27 | } 28 | log.SetOutput(openLogFile) 29 | return nil 30 | } 31 | 32 | func main() { 33 | filename := "/tmp/myLog.log" 34 | err := setUpLogFile(filename) 35 | if err != nil { 36 | fmt.Println(err) 37 | os.Exit(-1) 38 | } 39 | 40 | sigs := make(chan os.Signal, 1) 41 | signal.Notify(sigs) 42 | 43 | go func() { 44 | for { 45 | sig := <-sigs 46 | switch sig { 47 | case os.Interrupt: 48 | rotateLogFile(filename) 49 | TOTALWRITES++ 50 | case syscall.SIGTERM: 51 | log.Println("Got:", sig) 52 | openLogFile.Close() 53 | TOTALWRITES++ 54 | fmt.Println("Wrote", TOTALWRITES, "log entries in total!") 55 | os.Exit(-1) 56 | default: 57 | log.Println("Got:", sig) 58 | TOTALWRITES++ 59 | } 60 | } 61 | }() 62 | 63 | for { 64 | time.Sleep(10 * time.Second) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Chapter08/writeSTDOUT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | myString := "" 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | myString = "You do not give an argument!" 13 | } else { 14 | myString = arguments[1] 15 | } 16 | 17 | buf := []byte(myString) 18 | io.WriteString(os.Stdout, string(buf)) 19 | io.WriteString(os.Stdout, "\n") 20 | } 21 | -------------------------------------------------------------------------------- /Chapter09/aGoroutine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func namedFunction() { 9 | time.Sleep(10000) 10 | fmt.Println("Printing from namedFunction!") 11 | } 12 | 13 | func main() { 14 | fmt.Println("Chapter 09 - Goroutines.") 15 | 16 | go namedFunction() 17 | 18 | go func() { 19 | fmt.Println("An anonymous function!") 20 | }() 21 | 22 | time.Sleep(10000) 23 | fmt.Println("Exiting...") 24 | } 25 | -------------------------------------------------------------------------------- /Chapter09/dWC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "path/filepath" 9 | "regexp" 10 | "sync" 11 | ) 12 | 13 | func count(filename string) { 14 | var err error 15 | var numberOfLines int = 0 16 | var numberOfCharacters int = 0 17 | var numberOfWords int = 0 18 | 19 | f, err := os.Open(filename) 20 | if err != nil { 21 | fmt.Printf("%s\n", err) 22 | return 23 | } 24 | defer f.Close() 25 | 26 | r := bufio.NewReader(f) 27 | for { 28 | line, err := r.ReadString('\n') 29 | 30 | if err == io.EOF { 31 | break 32 | } else if err != nil { 33 | fmt.Printf("error reading file %s\n", err) 34 | } 35 | numberOfLines++ 36 | r := regexp.MustCompile("[^\\s]+") 37 | for range r.FindAllString(line, -1) { 38 | numberOfWords++ 39 | } 40 | numberOfCharacters += len(line) 41 | } 42 | 43 | fmt.Printf("\t%d\t", numberOfLines) 44 | fmt.Printf("%d\t", numberOfWords) 45 | fmt.Printf("%d\t", numberOfCharacters) 46 | fmt.Printf("%s\n", filename) 47 | } 48 | 49 | func main() { 50 | if len(os.Args) == 1 { 51 | fmt.Printf("usage: %s [ [... [ [... n2 { 43 | fmt.Printf("%d should be smaller than %d\n", n1, n2) 44 | os.Exit(10) 45 | } 46 | 47 | naturals := make(chan int64) 48 | squares := make(chan int64) 49 | go genNumbers(n1, n2, naturals) 50 | go findSquares(squares, naturals) 51 | calcSum(squares) 52 | } 53 | -------------------------------------------------------------------------------- /Chapter09/readChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeChannel(c chan<- int, x int) { 9 | fmt.Println(x) 10 | c <- x 11 | close(c) 12 | fmt.Println(x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeChannel(c, 10) 18 | time.Sleep(2 * time.Second) 19 | fmt.Println("Read:", <-c) 20 | time.Sleep(2 * time.Second) 21 | 22 | _, ok := <-c 23 | if ok { 24 | fmt.Println("Channel is open!") 25 | } else { 26 | fmt.Println("Channel is closed!") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter09/waitGR.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Waiting for Goroutines!") 10 | 11 | var waitGroup sync.WaitGroup 12 | waitGroup.Add(10) 13 | var i int64 14 | for i = 0; i < 10; i++ { 15 | 16 | go func(x int64) { 17 | defer waitGroup.Done() 18 | fmt.Printf("%d ", x) 19 | }(i) 20 | } 21 | 22 | waitGroup.Wait() 23 | fmt.Println("\nExiting...") 24 | } 25 | -------------------------------------------------------------------------------- /Chapter09/writeChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeChannel(c chan<- int, x int) { 9 | fmt.Println(x) 10 | c <- x 11 | close(c) 12 | fmt.Println(x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeChannel(c, 10) 18 | time.Sleep(2 * time.Second) 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/WCbuffered.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "path/filepath" 9 | "regexp" 10 | ) 11 | 12 | type File struct { 13 | Filename string 14 | Lines int 15 | Words int 16 | Characters int 17 | Error error 18 | } 19 | 20 | func monitor(values <-chan File, count int) { 21 | var totalWords int = 0 22 | var totalLines int = 0 23 | var totalChars int = 0 24 | for i := 0; i < count; i++ { 25 | x := <-values 26 | totalWords = totalWords + x.Words 27 | totalLines = totalLines + x.Lines 28 | totalChars = totalChars + x.Characters 29 | if x.Error == nil { 30 | fmt.Printf("\t%d\t", x.Lines) 31 | fmt.Printf("%d\t", x.Words) 32 | fmt.Printf("%d\t", x.Characters) 33 | fmt.Printf("%s\n", x.Filename) 34 | } else { 35 | fmt.Printf("\t%s\n", x.Error) 36 | } 37 | } 38 | fmt.Printf("\t%d\t", totalLines) 39 | fmt.Printf("%d\t", totalWords) 40 | fmt.Printf("%d\ttotal\n", totalChars) 41 | } 42 | 43 | func count(filename string, out chan<- File) { 44 | var err error 45 | var nLines int = 0 46 | var nChars int = 0 47 | var nWords int = 0 48 | 49 | f, err := os.Open(filename) 50 | defer f.Close() 51 | if err != nil { 52 | newValue := File{Filename: filename, Lines: 0, Characters: 0, Words: 0, Error: err} 53 | out <- newValue 54 | return 55 | } 56 | 57 | r := bufio.NewReader(f) 58 | for { 59 | line, err := r.ReadString('\n') 60 | 61 | if err == io.EOF { 62 | break 63 | } else if err != nil { 64 | fmt.Printf("error reading file %s\n", err) 65 | } 66 | nLines++ 67 | r := regexp.MustCompile("[^\\s]+") 68 | for range r.FindAllString(line, -1) { 69 | nWords++ 70 | } 71 | nChars += len(line) 72 | } 73 | newValue := File{Filename: filename, Lines: nLines, Characters: nChars, Words: nWords, Error: nil} 74 | out <- newValue 75 | } 76 | 77 | func main() { 78 | if len(os.Args) == 1 { 79 | fmt.Printf("usage: %s [ [... [ [... %s\n", read()) 46 | fmt.Printf("Length: %d\n", len(read())) 47 | } 48 | -------------------------------------------------------------------------------- /Chapter10/nilChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func addIntegers(c chan int) { 10 | sum := 0 11 | t := time.NewTimer(time.Second) 12 | 13 | for { 14 | select { 15 | case input := <-c: 16 | sum = sum + input 17 | case <-t.C: 18 | c = nil 19 | fmt.Println(sum) 20 | } 21 | } 22 | } 23 | 24 | func sendIntegers(c chan int) { 25 | for { 26 | c <- rand.Intn(100) 27 | } 28 | } 29 | 30 | func main() { 31 | c := make(chan int) 32 | go addIntegers(c) 33 | go sendIntegers(c) 34 | 35 | time.Sleep(2 * time.Second) 36 | } 37 | -------------------------------------------------------------------------------- /Chapter10/rd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strconv" 8 | "sync" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) != 2 { 14 | fmt.Printf("usage: %s number\n", filepath.Base(arguments[0])) 15 | os.Exit(1) 16 | } 17 | numGR, _ := strconv.ParseInt(os.Args[1], 10, 64) 18 | var waitGroup sync.WaitGroup 19 | var i int64 20 | 21 | for i = 0; i < numGR; i++ { 22 | waitGroup.Add(1) 23 | go func() { 24 | defer waitGroup.Done() 25 | fmt.Printf("%d ", i) 26 | }() 27 | } 28 | waitGroup.Wait() 29 | fmt.Println("\nExiting...") 30 | } 31 | -------------------------------------------------------------------------------- /Chapter10/sharedMem.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | var readValue = make(chan int) 11 | var writeValue = make(chan int) 12 | 13 | func SetValue(newValue int) { 14 | writeValue <- newValue 15 | } 16 | 17 | func ReadValue() int { 18 | return <-readValue 19 | } 20 | 21 | func monitor() { 22 | var value int 23 | for { 24 | select { 25 | case newValue := <-writeValue: 26 | value = newValue 27 | fmt.Printf("%d ", value) 28 | case readValue <- value: 29 | } 30 | } 31 | } 32 | 33 | func main() { 34 | rand.Seed(time.Now().Unix()) 35 | go monitor() 36 | var waitGroup sync.WaitGroup 37 | 38 | for r := 0; r < 20; r++ { 39 | waitGroup.Add(1) 40 | go func() { 41 | defer waitGroup.Done() 42 | SetValue(rand.Intn(100)) 43 | }() 44 | } 45 | waitGroup.Wait() 46 | fmt.Printf("\nLast value: %d\n", ReadValue()) 47 | } 48 | -------------------------------------------------------------------------------- /Chapter10/signalChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func A(a, b, c chan struct{}) { 9 | <-a 10 | fmt.Println("A!") 11 | time.Sleep(time.Second) 12 | close(b) 13 | } 14 | 15 | func B(b, c chan struct{}) { 16 | <-b 17 | fmt.Println("B!") 18 | close(c) 19 | } 20 | 21 | func C(a chan struct{}) { 22 | <-a 23 | fmt.Println("C!") 24 | } 25 | 26 | func main() { 27 | a := make(chan struct{}) 28 | b := make(chan struct{}) 29 | c := make(chan struct{}) 30 | 31 | go A(a, b, c) 32 | go C(c) 33 | go B(b, c) 34 | go C(c) 35 | 36 | close(a) 37 | time.Sleep(2 * time.Second) 38 | } 39 | -------------------------------------------------------------------------------- /Chapter10/timeOuts.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | c1 := make(chan string) 11 | go func() { 12 | time.Sleep(time.Second * 3) 13 | c1 <- "c1 OK" 14 | }() 15 | 16 | select { 17 | case res := <-c1: 18 | fmt.Println(res) 19 | case <-time.After(time.Second * 1): 20 | fmt.Println("timeout c1") 21 | } 22 | 23 | c2 := make(chan string) 24 | go func() { 25 | time.Sleep(time.Second * 3) 26 | c2 <- "c2 OK" 27 | }() 28 | 29 | select { 30 | case res := <-c2: 31 | fmt.Println(res) 32 | case <-time.After(time.Second * 4): 33 | fmt.Println("timeout c2") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter10/timeoutWait.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func timeout(w *sync.WaitGroup, t time.Duration) bool { 10 | temp := make(chan int) 11 | go func() { 12 | defer close(temp) 13 | w.Wait() 14 | }() 15 | 16 | select { 17 | case <-temp: 18 | return false 19 | case <-time.After(t): 20 | return true 21 | } 22 | } 23 | 24 | func main() { 25 | var w sync.WaitGroup 26 | w.Add(1) 27 | 28 | t := 2 * time.Second 29 | fmt.Printf("Timeout period is %s\n", t) 30 | 31 | if timeout(&w, t) { 32 | fmt.Println("Timed out!") 33 | } else { 34 | fmt.Println("OK!") 35 | } 36 | 37 | w.Done() 38 | if timeout(&w, t) { 39 | fmt.Println("Timed out!") 40 | } else { 41 | fmt.Println("OK!") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Chapter10/useSelect.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "path/filepath" 8 | "strconv" 9 | "time" 10 | ) 11 | 12 | func createNumber(max int, randomNumberChannel chan<- int, finishedChannel chan bool) { 13 | for { 14 | select { 15 | case randomNumberChannel <- rand.Intn(max): 16 | case x := <-finishedChannel: 17 | if x == true { 18 | close(finishedChannel) 19 | close(randomNumberChannel) 20 | return 21 | } 22 | } 23 | } 24 | } 25 | 26 | func main() { 27 | rand.Seed(time.Now().Unix()) 28 | randomNumberChannel := make(chan int) 29 | finishedChannel := make(chan bool) 30 | 31 | if len(os.Args) != 3 { 32 | fmt.Printf("usage: %s count max\n", filepath.Base(os.Args[0])) 33 | os.Exit(1) 34 | } 35 | 36 | n1, _ := strconv.ParseInt(os.Args[1], 10, 64) 37 | count := int(n1) 38 | n2, _ := strconv.ParseInt(os.Args[2], 10, 64) 39 | max := int(n2) 40 | 41 | fmt.Printf("Going to create %d random numbers.\n", count) 42 | go createNumber(max, randomNumberChannel, finishedChannel) 43 | for i := 0; i < count; i++ { 44 | fmt.Printf("%d ", <-randomNumberChannel) 45 | } 46 | 47 | finishedChannel <- false 48 | fmt.Println() 49 | _, ok := <-randomNumberChannel 50 | if ok { 51 | fmt.Println("Channel is open!") 52 | } else { 53 | fmt.Println("Channel is closed!") 54 | } 55 | 56 | finishedChannel <- true 57 | _, ok = <-randomNumberChannel 58 | if ok { 59 | fmt.Println("Channel is open!") 60 | } else { 61 | fmt.Println("Channel is closed!") 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Chapter11/findKeyword.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net/http" 7 | "net/url" 8 | "os" 9 | "regexp" 10 | ) 11 | 12 | type Data struct { 13 | URL string 14 | Keyword string 15 | Times int 16 | Error error 17 | } 18 | 19 | func monitor(values <-chan Data, count int) { 20 | for i := 0; i < count; i++ { 21 | x := <-values 22 | if x.Error == nil { 23 | fmt.Printf("\t%s\t", x.Keyword) 24 | fmt.Printf("\t%d\t in\t%s\n", x.Times, x.URL) 25 | } else { 26 | fmt.Printf("\t%s\n", x.Error) 27 | } 28 | } 29 | } 30 | 31 | func processPage(myUrl, keyword string, out chan<- Data) { 32 | var err error 33 | times := 0 34 | 35 | URL, err := url.Parse(myUrl) 36 | if err != nil { 37 | out <- Data{URL: myUrl, Keyword: keyword, Times: 0, Error: err} 38 | return 39 | } 40 | 41 | c := &http.Client{} 42 | request, err := http.NewRequest("GET", URL.String(), nil) 43 | if err != nil { 44 | out <- Data{URL: myUrl, Keyword: keyword, Times: 0, Error: err} 45 | return 46 | } 47 | 48 | httpData, err := c.Do(request) 49 | if err != nil { 50 | out <- Data{URL: myUrl, Keyword: keyword, Times: 0, Error: err} 51 | return 52 | } 53 | 54 | bodyHTML := "" 55 | var buffer [1024]byte 56 | reader := httpData.Body 57 | for { 58 | n, err := reader.Read(buffer[0:]) 59 | if err != nil { 60 | break 61 | } 62 | bodyHTML = bodyHTML + string(buffer[0:n]) 63 | } 64 | 65 | regExpr := keyword 66 | r := regexp.MustCompile(regExpr) 67 | matches := r.FindAllString(bodyHTML, -1) 68 | times = times + len(matches) 69 | 70 | newValue := Data{URL: myUrl, Keyword: keyword, Times: times, Error: nil} 71 | out <- newValue 72 | } 73 | 74 | func main() { 75 | filename := "" 76 | var f *os.File 77 | var keyword string 78 | 79 | arguments := os.Args 80 | if len(arguments) == 1 { 81 | fmt.Println("Not enough arguments!") 82 | os.Exit(-1) 83 | } 84 | 85 | if len(arguments) == 2 { 86 | f = os.Stdin 87 | keyword = arguments[1] 88 | } else { 89 | keyword = arguments[1] 90 | filename = arguments[2] 91 | fileHandler, err := os.Open(filename) 92 | if err != nil { 93 | fmt.Printf("error opening %s: %s", filename, err) 94 | os.Exit(1) 95 | } 96 | f = fileHandler 97 | } 98 | 99 | defer f.Close() 100 | values := make(chan Data, len(os.Args[1:])) 101 | 102 | scanner := bufio.NewScanner(f) 103 | count := 0 104 | for scanner.Scan() { 105 | count = count + 1 106 | go func(URL string) { 107 | processPage(URL, keyword, values) 108 | }(scanner.Text()) 109 | } 110 | 111 | monitor(values, count) 112 | } 113 | -------------------------------------------------------------------------------- /Chapter11/getURL.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 14 | os.Exit(1) 15 | } 16 | 17 | URL := os.Args[1] 18 | data, err := http.Get(URL) 19 | 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(100) 23 | } else { 24 | defer data.Body.Close() 25 | _, err := io.Copy(os.Stdout, data.Body) 26 | if err != nil { 27 | fmt.Println(err) 28 | os.Exit(100) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter11/marUnmar.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func main() { 21 | myRecord := Record{ 22 | Name: "Mihalis", 23 | Surname: "Tsoukalos", 24 | Tel: []Telephone{Telephone{Mobile: true, Number: "1234-567"}, 25 | Telephone{Mobile: true, Number: "1234-abcd"}, 26 | Telephone{Mobile: false, Number: "abcc-567"}, 27 | }} 28 | 29 | rec, err := json.Marshal(&myRecord) 30 | if err != nil { 31 | fmt.Println(err) 32 | os.Exit(100) 33 | } 34 | fmt.Println(string(rec)) 35 | 36 | var unRec Record 37 | err1 := json.Unmarshal(rec, &unRec) 38 | if err1 != nil { 39 | fmt.Println(err1) 40 | os.Exit(100) 41 | } 42 | fmt.Println(unRec) 43 | } 44 | -------------------------------------------------------------------------------- /Chapter11/mongoDB.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Displaying MongoDB data 6 | 14 | 15 | 16 | 17 |

Displaying Dynamic MongoDB content!

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{ range . }} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {{ end }} 39 | 40 |
P 1P 2P 3P 4P 5
{{ .P1 }} {{ .P2 }} {{ .P3 }} {{ .P4 }} {{ .P5 }}
41 | 42 | 43 | -------------------------------------------------------------------------------- /Chapter11/readJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func loadFromJSON(filename string, key interface{}) error { 21 | in, err := os.Open(filename) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | decodeJSON := json.NewDecoder(in) 27 | err = decodeJSON.Decode(key) 28 | if err != nil { 29 | return err 30 | } 31 | in.Close() 32 | return nil 33 | } 34 | 35 | func main() { 36 | arguments := os.Args 37 | if len(arguments) == 1 { 38 | fmt.Println("Please provide a filename!") 39 | os.Exit(100) 40 | } 41 | 42 | filename := arguments[1] 43 | 44 | var myRecord Record 45 | err := loadFromJSON(filename, &myRecord) 46 | if err == nil { 47 | fmt.Println(myRecord) 48 | } else { 49 | fmt.Println(err) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter11/serveMux.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func about(w http.ResponseWriter, r *http.Request) { 10 | fmt.Fprintf(w, "This is the /about page at %s\n", r.URL.Path) 11 | fmt.Printf("Served: %s\n", r.Host) 12 | } 13 | 14 | func cv(w http.ResponseWriter, r *http.Request) { 15 | fmt.Fprintf(w, "This is the /CV page at %s\n", r.URL.Path) 16 | fmt.Printf("Served: %s\n", r.Host) 17 | } 18 | 19 | func timeHandler(w http.ResponseWriter, r *http.Request) { 20 | currentTime := time.Now().Format(time.RFC1123) 21 | title := currentTime 22 | Body := "The current time is:" 23 | fmt.Fprintf(w, "

%s

%s

", Body, title) 24 | fmt.Printf("Served: %s for %s\n", r.URL.Path, r.Host) 25 | } 26 | 27 | func home(w http.ResponseWriter, r *http.Request) { 28 | if r.URL.Path == "/" { 29 | fmt.Fprintf(w, "Welcome to my home page!\n") 30 | } else { 31 | fmt.Fprintf(w, "Unknown page: %s from %s\n", r.URL.Path, r.Host) 32 | } 33 | fmt.Printf("Served: %s for %s\n", r.URL.Path, r.Host) 34 | } 35 | 36 | func main() { 37 | m := http.NewServeMux() 38 | m.HandleFunc("/about", about) 39 | m.HandleFunc("/CV", cv) 40 | m.HandleFunc("/time", timeHandler) 41 | m.HandleFunc("/", home) 42 | 43 | http.ListenAndServe(":8001", m) 44 | } 45 | -------------------------------------------------------------------------------- /Chapter11/showMongo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "labix.org/v2/mgo" 7 | "net/http" 8 | "os" 9 | "time" 10 | ) 11 | 12 | var DatabaseName string 13 | var collectionName string 14 | 15 | type Document struct { 16 | P1 int 17 | P2 int 18 | P3 int 19 | P4 int 20 | P5 int 21 | } 22 | 23 | func content(w http.ResponseWriter, r *http.Request) { 24 | var Data []Document 25 | myT := template.Must(template.ParseGlob("mongoDB.gohtml")) 26 | 27 | mongoDBDialInfo := &mgo.DialInfo{ 28 | Addrs: []string{"127.0.0.1:27017"}, 29 | Timeout: 20 * time.Second, 30 | } 31 | 32 | session, err := mgo.DialWithInfo(mongoDBDialInfo) 33 | if err != nil { 34 | fmt.Printf("DialWithInfo: %s\n", err) 35 | return 36 | } 37 | session.SetMode(mgo.Monotonic, true) 38 | c := session.DB(DatabaseName).C(collectionName) 39 | 40 | err = c.Find(nil).All(&Data) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | 46 | fmt.Println("Found:", len(Data), "results!") 47 | myT.ExecuteTemplate(w, "mongoDB.gohtml", Data) 48 | } 49 | 50 | func main() { 51 | arguments := os.Args 52 | 53 | if len(arguments) <= 2 { 54 | fmt.Println("Please provide a Database and a Collection!") 55 | os.Exit(100) 56 | } else { 57 | DatabaseName = arguments[1] 58 | collectionName = arguments[2] 59 | } 60 | 61 | http.HandleFunc("/", content) 62 | http.ListenAndServe(":8001", nil) 63 | } 64 | -------------------------------------------------------------------------------- /Chapter11/showMySQL.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | _ "github.com/go-sql-driver/mysql" 7 | "os" 8 | "text/template" 9 | ) 10 | 11 | func main() { 12 | var username string 13 | var password string 14 | 15 | arguments := os.Args 16 | if len(arguments) == 3 { 17 | username = arguments[1] 18 | password = arguments[2] 19 | } else { 20 | fmt.Println("programName Username Password!") 21 | os.Exit(100) 22 | } 23 | 24 | connectString := username + ":" + password + "@unix(/tmp/mysql.sock)/information_schema" 25 | db, err := sql.Open("mysql", connectString) 26 | 27 | rows, err := db.Query("SELECT DISTINCT(TABLE_SCHEMA) FROM TABLES;") 28 | if err != nil { 29 | fmt.Println(err) 30 | os.Exit(100) 31 | } 32 | 33 | var DATABASES []string 34 | for rows.Next() { 35 | var databaseName string 36 | err := rows.Scan(&databaseName) 37 | if err != nil { 38 | fmt.Println(err) 39 | os.Exit(100) 40 | } 41 | DATABASES = append(DATABASES, databaseName) 42 | } 43 | db.Close() 44 | 45 | t := template.Must(template.New("t1").Parse(` 46 | {{range $k := .}} {{ printf "\tDatabase Name: %s" $k}} 47 | {{end}} 48 | `)) 49 | t.Execute(os.Stdout, DATABASES) 50 | fmt.Println() 51 | } 52 | -------------------------------------------------------------------------------- /Chapter11/static.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Static HTML Template 6 | 7 | 8 | 9 |

Hello there!

10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter11/template.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "html/template" 7 | "net/http" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type Entry struct { 13 | WebSite string 14 | WebName string 15 | Quality string 16 | } 17 | 18 | var filename string 19 | 20 | func dynamicContent(w http.ResponseWriter, r *http.Request) { 21 | var Data []Entry 22 | var f *os.File 23 | if filename == "" { 24 | f = os.Stdin 25 | } else { 26 | fileHandler, err := os.Open(filename) 27 | if err != nil { 28 | fmt.Printf("error opening %s: %s", filename, err) 29 | os.Exit(1) 30 | } 31 | f = fileHandler 32 | } 33 | defer f.Close() 34 | 35 | myT := template.Must(template.ParseGlob("template.gohtml")) 36 | scanner := bufio.NewScanner(f) 37 | for scanner.Scan() { 38 | 39 | parts := strings.Fields(scanner.Text()) 40 | if len(parts) == 3 { 41 | temp := Entry{WebSite: parts[0], WebName: parts[1], Quality: parts[2]} 42 | Data = append(Data, temp) 43 | } 44 | } 45 | 46 | fmt.Println("Serving", r.Host, "for", r.URL.Path) 47 | myT.ExecuteTemplate(w, "template.gohtml", Data) 48 | } 49 | 50 | func staticPage(w http.ResponseWriter, r *http.Request) { 51 | fmt.Println("Serving", r.Host, "for", r.URL.Path) 52 | myT := template.Must(template.ParseGlob("static.gohtml")) 53 | myT.ExecuteTemplate(w, "static.gohtml", nil) 54 | } 55 | 56 | func main() { 57 | arguments := os.Args 58 | 59 | if len(arguments) == 1 { 60 | filename = "" 61 | } else { 62 | filename = arguments[1] 63 | } 64 | 65 | http.HandleFunc("/static", staticPage) 66 | http.HandleFunc("/dynamic", dynamicContent) 67 | http.ListenAndServe(":8001", nil) 68 | } 69 | -------------------------------------------------------------------------------- /Chapter11/template.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Using Go HTML Templates 6 | 14 | 15 | 16 | 17 |

Presenting Dynamic content!

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {{ range . }} 28 | 29 | 30 | 31 | 32 | {{ end }} 33 | 34 |
Web SiteQuality
{{ .WebName }} {{ .Quality }}
35 | 36 | 37 | -------------------------------------------------------------------------------- /Chapter11/testMongo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "labix.org/v2/mgo" 6 | "labix.org/v2/mgo/bson" 7 | "os" 8 | "time" 9 | ) 10 | 11 | type Record struct { 12 | Xvalue int 13 | Yvalue int 14 | } 15 | 16 | func main() { 17 | mongoDBDialInfo := &mgo.DialInfo{ 18 | Addrs: []string{"127.0.0.1:27017"}, 19 | Timeout: 20 * time.Second, 20 | } 21 | 22 | session, err := mgo.DialWithInfo(mongoDBDialInfo) 23 | if err != nil { 24 | fmt.Printf("DialWithInfo: %s\n", err) 25 | os.Exit(100) 26 | } 27 | session.SetMode(mgo.Monotonic, true) 28 | 29 | collection := session.DB("goDriver").C("someData") 30 | 31 | err = collection.Insert(&Record{1, 0}) 32 | if err != nil { 33 | fmt.Println(err) 34 | os.Exit(100) 35 | } 36 | 37 | err = collection.Insert(&Record{-1, 0}) 38 | if err != nil { 39 | fmt.Println(err) 40 | os.Exit(100) 41 | } 42 | 43 | var recs []Record 44 | err = collection.Find(bson.M{"yvalue": 0}).All(&recs) 45 | if err != nil { 46 | fmt.Println(err) 47 | os.Exit(100) 48 | } 49 | 50 | for x, y := range recs { 51 | fmt.Println(x, y) 52 | } 53 | fmt.Println("Found:", len(recs), "results!") 54 | } 55 | -------------------------------------------------------------------------------- /Chapter11/timeoutHTTP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "time" 11 | ) 12 | 13 | var timeout = time.Duration(time.Second) 14 | 15 | func Timeout(network, host string) (net.Conn, error) { 16 | conn, err := net.DialTimeout(network, host, timeout) 17 | if err != nil { 18 | return nil, err 19 | } 20 | conn.SetDeadline(time.Now().Add(timeout)) 21 | return conn, nil 22 | } 23 | 24 | func main() { 25 | if len(os.Args) != 2 { 26 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 27 | os.Exit(1) 28 | } 29 | 30 | URL := os.Args[1] 31 | t := http.Transport{ 32 | Dial: Timeout, 33 | } 34 | 35 | client := http.Client{ 36 | Transport: &t, 37 | } 38 | data, err := client.Get(URL) 39 | 40 | if err != nil { 41 | fmt.Println(err) 42 | os.Exit(100) 43 | } else { 44 | defer data.Body.Close() 45 | _, err := io.Copy(os.Stdout, data.Body) 46 | if err != nil { 47 | fmt.Println(err) 48 | os.Exit(100) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter11/webClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | func main() { 14 | if len(os.Args) != 2 { 15 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 16 | os.Exit(1) 17 | } 18 | 19 | URL, err := url.Parse(os.Args[1]) 20 | if err != nil { 21 | fmt.Println("Parse:", err) 22 | os.Exit(100) 23 | } 24 | 25 | c := &http.Client{} 26 | 27 | request, err := http.NewRequest("GET", URL.String(), nil) 28 | if err != nil { 29 | fmt.Println(err) 30 | os.Exit(100) 31 | } 32 | 33 | httpData, err := c.Do(request) 34 | if err != nil { 35 | fmt.Println(err) 36 | os.Exit(100) 37 | } 38 | 39 | fmt.Println("Status code:", httpData.Status) 40 | header, _ := httputil.DumpResponse(httpData, false) 41 | fmt.Print(string(header)) 42 | 43 | contentType := httpData.Header.Get("Content-Type") 44 | characterSet := strings.SplitAfter(contentType, "charset=") 45 | fmt.Println("Character Set:", characterSet[1]) 46 | 47 | if httpData.ContentLength == -1 { 48 | fmt.Println("ContentLength in unknown!") 49 | } else { 50 | fmt.Println("ContentLength:", httpData.ContentLength) 51 | } 52 | 53 | length := 0 54 | var buffer [1024]byte 55 | r := httpData.Body 56 | for { 57 | n, err := r.Read(buffer[0:]) 58 | if err != nil { 59 | fmt.Println(err) 60 | break 61 | } 62 | length = length + n 63 | } 64 | fmt.Println("Response data length:", length) 65 | } 66 | -------------------------------------------------------------------------------- /Chapter11/webServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func myHandler(w http.ResponseWriter, r *http.Request) { 10 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 11 | fmt.Printf("Served: %s\n", r.Host) 12 | } 13 | 14 | func main() { 15 | PORT := ":8001" 16 | arguments := os.Args 17 | if len(arguments) == 1 { 18 | fmt.Println("Using default port number: ", PORT) 19 | } else { 20 | PORT = ":" + arguments[1] 21 | } 22 | 23 | http.HandleFunc("/", myHandler) 24 | err := http.ListenAndServe(PORT, nil) 25 | if err != nil { 26 | fmt.Println(err) 27 | os.Exit(10) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter11/writeJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func saveToJSON(filename string, key interface{}) { 21 | out, err := os.Create(filename) 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | encodeJSON := json.NewEncoder(out) 28 | err = encodeJSON.Encode(key) 29 | if err != nil { 30 | fmt.Println(err) 31 | return 32 | } 33 | 34 | out.Close() 35 | } 36 | 37 | func main() { 38 | arguments := os.Args 39 | if len(arguments) == 1 { 40 | fmt.Println("Please provide a filename!") 41 | os.Exit(100) 42 | } 43 | 44 | filename := arguments[1] 45 | myRecord := Record{ 46 | Name: "Mihalis", 47 | Surname: "Tsoukalos", 48 | Tel: []Telephone{Telephone{Mobile: true, Number: "1234-567"}, 49 | Telephone{Mobile: true, Number: "1234-abcd"}, 50 | Telephone{Mobile: false, Number: "abcc-567"}, 51 | }} 52 | 53 | saveToJSON(filename, myRecord) 54 | } 55 | -------------------------------------------------------------------------------- /Chapter12/RPCclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/rpc" 6 | "os" 7 | "sharedRPC" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a host:port string!") 14 | os.Exit(100) 15 | } 16 | 17 | CONNECT := arguments[1] 18 | c, err := rpc.Dial("tcp", CONNECT) 19 | if err != nil { 20 | fmt.Println(err) 21 | os.Exit(100) 22 | } 23 | 24 | args := sharedRPC.MyInts{17, 18, true, false} 25 | var reply int 26 | 27 | err = c.Call("MyInterface.Add", args, &reply) 28 | if err != nil { 29 | fmt.Println(err) 30 | os.Exit(100) 31 | } 32 | fmt.Printf("Reply (Add): %d\n", reply) 33 | 34 | err = c.Call("MyInterface.Subtract", args, &reply) 35 | if err != nil { 36 | fmt.Println(err) 37 | os.Exit(100) 38 | } 39 | fmt.Printf("Reply (Subtract): %d\n", reply) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Chapter12/RPCserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "net/rpc" 7 | "os" 8 | "sharedRPC" 9 | ) 10 | 11 | type MyInterface int 12 | 13 | func (t *MyInterface) Add(arguments *sharedRPC.MyInts, reply *int) error { 14 | s1 := 1 15 | s2 := 1 16 | 17 | if arguments.S1 == true { 18 | s1 = -1 19 | } 20 | 21 | if arguments.S2 == true { 22 | s2 = -1 23 | } 24 | 25 | *reply = s1*int(arguments.A1) + s2*int(arguments.A2) 26 | return nil 27 | } 28 | 29 | func (t *MyInterface) Subtract(arguments *sharedRPC.MyInts, reply *int) error { 30 | s1 := 1 31 | s2 := 1 32 | 33 | if arguments.S1 == true { 34 | s1 = -1 35 | } 36 | 37 | if arguments.S2 == true { 38 | s2 = -1 39 | } 40 | 41 | *reply = s1*int(arguments.A1) - s2*int(arguments.A2) 42 | return nil 43 | } 44 | 45 | func main() { 46 | PORT := ":1234" 47 | 48 | myInterface := new(MyInterface) 49 | rpc.Register(myInterface) 50 | 51 | t, err := net.ResolveTCPAddr("tcp", PORT) 52 | if err != nil { 53 | fmt.Println(err) 54 | os.Exit(100) 55 | } 56 | l, err := net.ListenTCP("tcp", t) 57 | if err != nil { 58 | fmt.Println(err) 59 | os.Exit(100) 60 | } 61 | 62 | for { 63 | c, err := l.Accept() 64 | if err != nil { 65 | continue 66 | } 67 | rpc.ServeConn(c) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Chapter12/TCPc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide a server:port string!") 13 | os.Exit(100) 14 | } 15 | 16 | CONNECT := arguments[1] 17 | myMessage := "Hello from TCP client!\n" 18 | 19 | tcpAddr, err := net.ResolveTCPAddr("tcp", CONNECT) 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(100) 23 | } 24 | 25 | conn, err := net.DialTCP("tcp", nil, tcpAddr) 26 | if err != nil { 27 | fmt.Println(err) 28 | os.Exit(100) 29 | } 30 | 31 | _, err = conn.Write([]byte(myMessage)) 32 | if err != nil { 33 | fmt.Println(err) 34 | os.Exit(100) 35 | } 36 | 37 | fmt.Print("-> ", myMessage) 38 | buffer := make([]byte, 1024) 39 | 40 | n, err := conn.Read(buffer) 41 | if err != nil { 42 | fmt.Println(err) 43 | os.Exit(100) 44 | } 45 | 46 | fmt.Print(">> ", string(buffer[0:n])) 47 | conn.Close() 48 | } 49 | -------------------------------------------------------------------------------- /Chapter12/TCPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide host:port.") 15 | os.Exit(100) 16 | } 17 | 18 | CONNECT := arguments[1] 19 | c, err := net.Dial("tcp", CONNECT) 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(100) 23 | } 24 | 25 | for { 26 | reader := bufio.NewReader(os.Stdin) 27 | fmt.Print(">> ") 28 | text, _ := reader.ReadString('\n') 29 | fmt.Fprintf(c, text+"\n") 30 | 31 | message, _ := bufio.NewReader(c).ReadString('\n') 32 | fmt.Print("->: " + message) 33 | if strings.TrimSpace(string(text)) == "STOP" { 34 | fmt.Println("TCP client exiting...") 35 | return 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Chapter12/TCPs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide a port number!") 13 | os.Exit(100) 14 | } 15 | 16 | SERVER := "localhost" + ":" + arguments[1] 17 | 18 | s, err := net.ResolveTCPAddr("tcp", SERVER) 19 | if err != nil { 20 | fmt.Println(err) 21 | os.Exit(100) 22 | } 23 | 24 | l, err := net.ListenTCP("tcp", s) 25 | if err != nil { 26 | fmt.Println(err) 27 | os.Exit(100) 28 | } 29 | 30 | buffer := make([]byte, 1024) 31 | 32 | for { 33 | conn, err := l.Accept() 34 | n, err := conn.Read(buffer) 35 | if err != nil { 36 | fmt.Println(err) 37 | os.Exit(100) 38 | } 39 | 40 | fmt.Print("> ", string(buffer[0:n])) 41 | _, err = conn.Write(buffer) 42 | 43 | conn.Close() 44 | if err != nil { 45 | fmt.Println(err) 46 | os.Exit(100) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Chapter12/TCPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide port number") 15 | os.Exit(100) 16 | } 17 | 18 | PORT := ":" + arguments[1] 19 | l, err := net.Listen("tcp", PORT) 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(100) 23 | } 24 | defer l.Close() 25 | 26 | c, err := l.Accept() 27 | if err != nil { 28 | fmt.Println(err) 29 | os.Exit(100) 30 | } 31 | 32 | for { 33 | netData, err := bufio.NewReader(c).ReadString('\n') 34 | if err != nil { 35 | fmt.Println(err) 36 | os.Exit(100) 37 | } 38 | 39 | fmt.Print("-> ", string(netData)) 40 | c.Write([]byte(netData)) 41 | if strings.TrimSpace(string(netData)) == "STOP" { 42 | fmt.Println("Exiting TCP server!") 43 | return 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Chapter12/UDPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide a host:port string") 13 | os.Exit(100) 14 | } 15 | CONNECT := arguments[1] 16 | 17 | s, err := net.ResolveUDPAddr("udp", CONNECT) 18 | c, err := net.DialUDP("udp", nil, s) 19 | 20 | if err != nil { 21 | fmt.Println(err) 22 | os.Exit(100) 23 | } 24 | 25 | fmt.Printf("The UDP server is %s\n", c.RemoteAddr().String()) 26 | defer c.Close() 27 | 28 | data := []byte("Hello UDP Echo server!\n") 29 | _, err = c.Write(data) 30 | 31 | if err != nil { 32 | fmt.Println(err) 33 | os.Exit(100) 34 | } 35 | 36 | buffer := make([]byte, 1024) 37 | n, _, err := c.ReadFromUDP(buffer) 38 | fmt.Print("Reply: ", string(buffer[:n])) 39 | } 40 | -------------------------------------------------------------------------------- /Chapter12/UDPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a port number!") 14 | os.Exit(100) 15 | } 16 | PORT := ":" + arguments[1] 17 | 18 | s, err := net.ResolveUDPAddr("udp", PORT) 19 | if err != nil { 20 | fmt.Println(err) 21 | os.Exit(100) 22 | } 23 | 24 | connection, err := net.ListenUDP("udp", s) 25 | if err != nil { 26 | fmt.Println(err) 27 | os.Exit(100) 28 | } 29 | 30 | defer connection.Close() 31 | buffer := make([]byte, 1024) 32 | 33 | for { 34 | n, addr, err := connection.ReadFromUDP(buffer) 35 | fmt.Print("-> ", string(buffer[0:n])) 36 | data := []byte(buffer[0:n]) 37 | _, err = connection.WriteToUDP(data, addr) 38 | if err != nil { 39 | fmt.Println(err) 40 | os.Exit(100) 41 | } 42 | 43 | if strings.TrimSpace(string(data)) == "STOP" { 44 | fmt.Println("Exiting UDP server!") 45 | return 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chapter12/concTCP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | func handleConnection(c net.Conn) { 13 | for { 14 | netData, err := bufio.NewReader(c).ReadString('\n') 15 | if err != nil { 16 | fmt.Println(err) 17 | os.Exit(100) 18 | } 19 | 20 | fmt.Print("-> ", string(netData)) 21 | c.Write([]byte(netData)) 22 | if strings.TrimSpace(string(netData)) == "STOP" { 23 | break 24 | } 25 | } 26 | time.Sleep(3 * time.Second) 27 | c.Close() 28 | } 29 | 30 | func main() { 31 | arguments := os.Args 32 | if len(arguments) == 1 { 33 | fmt.Println("Please provide a port number!") 34 | os.Exit(100) 35 | } 36 | 37 | PORT := ":" + arguments[1] 38 | l, err := net.Listen("tcp", PORT) 39 | if err != nil { 40 | fmt.Println(err) 41 | os.Exit(100) 42 | } 43 | defer l.Close() 44 | 45 | for { 46 | c, err := l.Accept() 47 | if err != nil { 48 | fmt.Println(err) 49 | os.Exit(100) 50 | } 51 | go handleConnection(c) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Chapter12/handshake.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Go-Systems-Programming/81b8b0c039fc5870913436be5753378609727423/Chapter12/handshake.pcap -------------------------------------------------------------------------------- /Chapter12/lookHost.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide an argument!") 13 | os.Exit(100) 14 | } 15 | 16 | hostname := arguments[1] 17 | IPs, err := net.LookupHost(hostname) 18 | if err != nil { 19 | fmt.Println(err) 20 | os.Exit(100) 21 | } 22 | 23 | for _, IP := range IPs { 24 | fmt.Println(IP) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Chapter12/lookIP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide an IP address!") 13 | os.Exit(100) 14 | } 15 | 16 | IP := arguments[1] 17 | addr := net.ParseIP(IP) 18 | if addr == nil { 19 | fmt.Println("Not a valid IP address!") 20 | os.Exit(100) 21 | } 22 | 23 | hosts, err := net.LookupAddr(IP) 24 | if err != nil { 25 | fmt.Println(err) 26 | os.Exit(100) 27 | } 28 | 29 | for _, hostname := range hosts { 30 | fmt.Println(hostname) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter12/lookNS.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Please provide a domain!") 13 | os.Exit(100) 14 | } 15 | 16 | domain := arguments[1] 17 | 18 | NSs, err := net.LookupNS(domain) 19 | if err != nil { 20 | fmt.Println(err) 21 | os.Exit(100) 22 | } 23 | 24 | for _, NS := range NSs { 25 | fmt.Println(NS.Host) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter12/sharedRPC.go: -------------------------------------------------------------------------------- 1 | package sharedRPC 2 | 3 | type MyInts struct { 4 | A1, A2 uint 5 | S1, S2 bool 6 | } 7 | 8 | type MyInterface interface { 9 | Add(arguments *MyInts, reply *int) error 10 | Subtract(arguments *MyInts, reply *int) error 11 | } 12 | -------------------------------------------------------------------------------- /Chapter12/socketClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func readSocket(r io.Reader) { 12 | buf := make([]byte, 1024) 13 | for { 14 | n, err := r.Read(buf[:]) 15 | if err != nil { 16 | fmt.Println(err) 17 | return 18 | } 19 | fmt.Println("-> ", string(buf[0:n])) 20 | } 21 | } 22 | 23 | func main() { 24 | arguments := os.Args 25 | if len(arguments) == 1 { 26 | fmt.Println("Please provide a socket file.") 27 | os.Exit(100) 28 | } 29 | socketFile := arguments[1] 30 | 31 | c, err := net.Dial("unix", socketFile) 32 | if err != nil { 33 | fmt.Println(err) 34 | os.Exit(100) 35 | } 36 | defer c.Close() 37 | 38 | go readSocket(c) 39 | for { 40 | _, err := c.Write([]byte("Hello Server!")) 41 | if err != nil { 42 | fmt.Println(err) 43 | os.Exit(100) 44 | } 45 | time.Sleep(1 * time.Second) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chapter12/socketServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func echoServer(c net.Conn) { 10 | for { 11 | buf := make([]byte, 1024) 12 | nr, err := c.Read(buf) 13 | if err != nil { 14 | return 15 | } 16 | 17 | data := buf[0:nr] 18 | fmt.Printf("->: %v\n", string(data)) 19 | _, err = c.Write(data) 20 | if err != nil { 21 | fmt.Println(err) 22 | } 23 | } 24 | } 25 | 26 | func main() { 27 | arguments := os.Args 28 | if len(arguments) == 1 { 29 | fmt.Println("Please provide a socket file.") 30 | os.Exit(100) 31 | } 32 | 33 | socketFile := arguments[1] 34 | 35 | l, err := net.Listen("unix", socketFile) 36 | if err != nil { 37 | fmt.Println(err) 38 | os.Exit(100) 39 | } 40 | 41 | for { 42 | fd, err := l.Accept() 43 | if err != nil { 44 | fmt.Println(err) 45 | os.Exit(100) 46 | } 47 | 48 | go echoServer(fd) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Go Systems Programming 5 | This is the code repository for [Go Systems Programming](https://www.packtpub.com/networking-and-servers/go-systems-programming?utm_source=github&utm_medium=repository&utm_campaign=9781787125643), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish. 6 | ## About the Book 7 | 8 | 9 | Go is the new systems programming language for Linux and UNIX systems. It is also the language in which some of the most prominent Cloud-level systems have been written, for instance Docker et al. Where C programmers used to rule, Go programmers are gaining considerable traction to write highly optimized systems programming code. 10 | 11 | Created by the original designers of C and UNIX, it expands the systems programmers toolkit to add a mature, clear programming language. Threads and networking code, as well as traditional systems application become easier to write since pointers are not relevant and garbage collection has been taken away the most problematic area for low-level systems code: memory management. 12 | 13 | This book opens up the world of high-performant systems to the beginning Go programmer. It does not get stuck on single systems or even system types, but tries to expand the original teachings from Unix system's level programming to all types of servers, the cloud and the web. 14 | 15 | ## Instructions and Navigation 16 | All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02. 17 | 18 | 19 | 20 | The code will look like the following: 21 | ``` 22 | package main 23 | 24 | import "fmt" 25 | import "os" 26 | 27 | func main() { 28 | arguments := os.Args 29 | for i := 0; i < len(arguments); i++ { 30 | fmt.Println(arguments[i]) 31 | } 32 | } 33 | ``` 34 | 35 | This book requires a computer running a Unix variant with a relatively recent Go version, which includes any machine running Mac OS X, macOS, or Linux. 36 | 37 | Apple used to call its operating system as Mac OS X followed by the version number; however, after Mac OS X 10.11 (El Capitan), Apple changed that, and Mac OS X 10.12 is now called macOS 10.12 (Sierra) – in this book, the terms Mac OS X and macOS are used interchangeably. Additionally, there is a big chance that by the time you read this book, the latest version of macOS will be macOS 10.13 (High Sierra). You can learn more about the various versions of macOS by visiting https://en.wikipedia.org/wiki/MacOS. 38 | 39 | All of the Go code in this book has been tested with Go 1.8.x running on a iMac using macOS 10.12 Sierra and with Go version 1.3.3 running on a Debian Linux machine. Most of the code can run on both Go versions without any code changes. However, when newer Go features are used, the code will fail to compile with Go 1.3.3—the book states the Go programs that will not compile with Go version 1.3.3 or require Go version 1.8 or newer. 40 | 41 | Please note that at the time of writing this text, the latest Go version is 1.9. Given the way Go works, you will be able to compile all the Go code of this book in newer Go versions without any changes. 42 | 43 | ## Related Products 44 | * [Go: Design Patterns for Real-World Projects](https://www.packtpub.com/application-development/go-design-patterns-real-world-projects?utm_source=github&utm_medium=repository&utm_campaign=9781788390552) 45 | 46 | * [Go: Building Web Applications](https://www.packtpub.com/application-development/go-building-web-applications?utm_source=github&utm_medium=repository&utm_campaign=9781787123496) 47 | 48 | * [Building Microservices with Go](https://www.packtpub.com/application-development/building-microservices-go?utm_source=github&utm_medium=repository&utm_campaign=9781786468666) 49 | 50 | ### Download a free PDF 51 | 52 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
53 |

https://packt.link/free-ebook/9781787125643

--------------------------------------------------------------------------------