From 21e5071beac9c7d6e14759ef132f56d4d8b9cb69 Mon Sep 17 00:00:00 2001 From: Amrit Panesar Date: Sun, 24 Dec 2017 06:41:35 -0800 Subject: [PATCH] Initial code Version 0.0.1! --- .gitignore | 118 +++++++++++++++++++++++++++++ .idea/go-fische.iml | 8 ++ .idea/go.imports.xml | 9 +++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ .idea/watcherTasks.xml | 29 +++++++ VERSION | 1 + README.md => docs/README.md | 0 _config.yml => docs/_config.yml | 0 docs/logo.png | Bin 0 -> 28632 bytes main.go | 129 ++++++++++++++++++++++++++++++++ 11 files changed, 308 insertions(+) create mode 100644 .idea/go-fische.iml create mode 100644 .idea/go.imports.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/watcherTasks.xml create mode 100644 VERSION rename README.md => docs/README.md (100%) rename _config.yml => docs/_config.yml (100%) create mode 100644 docs/logo.png create mode 100644 main.go diff --git a/.gitignore b/.gitignore index a1338d6..ddfc70b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +code/ + # Binaries for programs and plugins *.exe *.dll @@ -12,3 +14,119 @@ # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Linux template +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* +### macOS template +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### Windows template +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + diff --git a/.idea/go-fische.iml b/.idea/go-fische.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/go-fische.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/go.imports.xml b/.idea/go.imports.xml new file mode 100644 index 0000000..e39c1bd --- /dev/null +++ b/.idea/go.imports.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..64e6bba --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 0000000..500f3b7 --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..0e8428a --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 diff --git a/README.md b/docs/README.md similarity index 100% rename from README.md rename to docs/README.md diff --git a/_config.yml b/docs/_config.yml similarity index 100% rename from _config.yml rename to docs/_config.yml diff --git a/docs/logo.png b/docs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d2739e4c54ee8ab69946ace70ee62dcbcb585e91 GIT binary patch literal 28632 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 YY#pD0SHoGZDi2>(6g1>3W#0w;9|D5ltN;K2 literal 0 HcmV?d00001 diff --git a/main.go b/main.go new file mode 100644 index 0000000..e660295 --- /dev/null +++ b/main.go @@ -0,0 +1,129 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "net" + "os" + "strconv" + "time" + + "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +const AppName = "Go-Fiche" + +const slugMap = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789" + +var ( + GitCommit, + GitBranch, + GitState, + BuildDate, + Version string +) + +func init() { + pflag.BoolP("help", "h", false, "Prints this help message") + pflag.StringP("output", "o", "./code", "Relative or absolute path to the directory where you want to store user-posted pastes.") + pflag.StringP("domain", "d", "localhost", "This will be used as a prefix for an output received by the client. Value will be prepended with http[s].") + pflag.IntP("port", "p", 9999, "Port in which the service should listen on.") + pflag.BoolP("https", "S", false, fmt.Sprintf("If set, %s returns url with https prefix instead of http.", AppName)) + pflag.StringP("username", "u", "", fmt.Sprintf("%s will try to switch to the requested user on startup if any is provided.", AppName)) + pflag.IntP("buffer", "B", 32768, "This parameter defines size of the buffer used for getting data from the user. Maximum size (in bytes) of all input files is defined by this value.") + pflag.StringP("log", "l", "", "Log file. This file has to be user-writable.") + pflag.Parse() + viper.BindPFlags(pflag.CommandLine) + + if viper.GetBool("help") { + fmt.Printf("%s!\n Version %s, Built: %s [%s:%s-%s)\n\n", AppName, Version, BuildDate, GitBranch, GitCommit, GitState) + pflag.Usage() + os.Exit(2) + } + + if viper.GetBool("https") { + viper.Set("uriprefix", "https") + } else { + viper.Set("uriprefix", "http") + } +} + +func main() { + log.Printf("Starting %s on %s...", AppName, time.Now().Format(time.RFC822Z)) + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", viper.Get("port"))) + if err != nil { + // handle error + log.Fatalf("Could not bind to port: %d!", viper.Get("port")) + os.Exit(-1) + } + log.Printf("Server started listening on port: %d.", viper.Get("port")) + for { + conn, err := listener.Accept() + if err != nil { + log.Printf("Error on accepting connection!") + continue + } + go handleConnection(conn) + } + time.Sleep(5) + os.Exit(0) +} + +func generateSlug(seed int64) string { + stringSeed := fmt.Sprintf("%d", seed) + evenLength := (len(stringSeed) / 2) * 2 + digitHold := int64(0) + out := "" + for i := 0; i < evenLength; i += 2 { + digitHold, _ = strconv.ParseInt(stringSeed[i:i+2], 10, 8) + digitHold = digitHold % int64(len(slugMap)) + out += slugMap[digitHold : digitHold+1] + } + return out +} + +func handleConnection(conn net.Conn) { + remoteHost, err := net.LookupCNAME(conn.RemoteAddr().String()) + if err != nil { + remoteHost = conn.RemoteAddr().String() + } + defer func() { + log.Printf("Closing connection to: %s (%s).\n", remoteHost, conn.RemoteAddr()) + conn.Close() + }() + log.Printf("Incoming connection from: %s (%s).\n", remoteHost, conn.RemoteAddr()) + conn.SetReadDeadline(time.Now().Add(time.Second * 5)) + + slug := generateSlug(time.Now().UnixNano()) + slugFullpath := fmt.Sprintf("%s/%s", viper.GetString("output"), slug) + log.Printf("Writing file to %s", slugFullpath) + + file, err := os.Create(slugFullpath) + if err != nil { + log.Fatalf("Unable to create slug file: %s", slugFullpath) + return + } + + scanner := bufio.NewScanner(conn) + for scanner.Scan() { + file.WriteString(scanner.Text()) + file.Write([]byte("\n")) + conn.SetReadDeadline(time.Now().Add(time.Second * 5)) + } + + stat, _ := file.Stat() + if stat.Size() <= 0 { + file.Close() + log.Printf("0 bytes received, aborting...") + os.Remove(slugFullpath) + return + } else { + file.Close() + } + + log.Printf("Wrote %d bytes to %s", stat.Size(), slugFullpath) + + conn.Write([]byte(fmt.Sprintf("%s://%s/%s\r\n", viper.GetString("uriprefix"), viper.GetString("domain"), slug))) +}