func connector(context *cli.Context) int { config, configFilename, err := lib.GetConfig(context) if err != nil { fmt.Fprintf(os.Stderr, "Failed to read config file: %s", err) return 1 } logFileMaxBytes := config.LogFileMaxMegabytes * 1024 * 1024 var logWriter io.Writer logWriter, err = log.NewLogRoller(config.LogFileName, logFileMaxBytes, config.LogMaxFiles) if err != nil { fmt.Fprintf(os.Stderr, "Failed to start log roller: %s", err) return 1 } if context.Bool("log-to-console") { logWriter = io.MultiWriter(logWriter, os.Stderr) } logLevel, ok := log.LevelFromString(config.LogLevel) if !ok { fmt.Fprintf(os.Stderr, "Log level %s is not recognized", config.LogLevel) return 1 } log.SetLevel(logLevel) log.SetWriter(logWriter) if configFilename == "" { log.Info("No config file was found, so using defaults") } log.Error(lib.FullName) fmt.Println(lib.FullName) if !config.CloudPrintingEnable && !config.LocalPrintingEnable { log.Error("Cannot run connector with both local_printing_enable and cloud_printing_enable set to false") return 1 } if _, err := os.Stat(config.MonitorSocketFilename); !os.IsNotExist(err) { if err != nil { log.Errorf("Failed to stat monitor socket: %s", err) } else { log.Errorf( "A connector is already running, or the monitoring socket %s wasn't cleaned up properly", config.MonitorSocketFilename) } return 1 } jobs := make(chan *lib.Job, 10) xmppNotifications := make(chan xmpp.PrinterNotification, 5) var g *gcp.GoogleCloudPrint var x *xmpp.XMPP if config.CloudPrintingEnable { xmppPingTimeout, err := time.ParseDuration(config.XMPPPingTimeout) if err != nil { log.Fatalf("Failed to parse xmpp ping timeout: %s", err) return 1 } xmppPingInterval, err := time.ParseDuration(config.XMPPPingInterval) if err != nil { log.Fatalf("Failed to parse xmpp ping interval default: %s", err) return 1 } g, err = gcp.NewGoogleCloudPrint(config.GCPBaseURL, config.RobotRefreshToken, config.UserRefreshToken, config.ProxyName, config.GCPOAuthClientID, config.GCPOAuthClientSecret, config.GCPOAuthAuthURL, config.GCPOAuthTokenURL, config.GCPMaxConcurrentDownloads, jobs) if err != nil { log.Error(err) return 1 } x, err = xmpp.NewXMPP(config.XMPPJID, config.ProxyName, config.XMPPServer, config.XMPPPort, xmppPingTimeout, xmppPingInterval, g.GetRobotAccessToken, xmppNotifications) if err != nil { log.Error(err) return 1 } defer x.Quit() } cupsConnectTimeout, err := time.ParseDuration(config.CUPSConnectTimeout) if err != nil { log.Fatalf("Failed to parse CUPS connect timeout: %s", err) return 1 } c, err := cups.NewCUPS(config.CopyPrinterInfoToDisplayName, config.PrefixJobIDToJobTitle, config.DisplayNamePrefix, config.CUPSPrinterAttributes, config.CUPSMaxConnections, cupsConnectTimeout) if err != nil { log.Fatal(err) return 1 } defer c.Quit() var s *snmp.SNMPManager if config.SNMPEnable { log.Info("SNMP enabled") s, err = snmp.NewSNMPManager(config.SNMPCommunity, config.SNMPMaxConnections) if err != nil { log.Error(err) return 1 } defer s.Quit() } var priv *privet.Privet if config.LocalPrintingEnable { if g == nil { priv, err = privet.NewPrivet(jobs, config.GCPBaseURL, nil) } else { priv, err = privet.NewPrivet(jobs, config.GCPBaseURL, g.ProximityToken) } if err != nil { log.Error(err) return 1 } defer priv.Quit() } cupsPrinterPollInterval, err := time.ParseDuration(config.CUPSPrinterPollInterval) if err != nil { log.Fatalf("Failed to parse CUPS printer poll interval: %s", err) return 1 } pm, err := manager.NewPrinterManager(c, g, priv, s, cupsPrinterPollInterval, config.CUPSJobQueueSize, config.CUPSJobFullUsername, config.CUPSIgnoreRawPrinters, config.ShareScope, jobs, xmppNotifications) if err != nil { log.Error(err) return 1 } defer pm.Quit() m, err := monitor.NewMonitor(c, g, priv, pm, config.MonitorSocketFilename) if err != nil { log.Error(err) return 1 } defer m.Quit() if config.CloudPrintingEnable { if config.LocalPrintingEnable { log.Errorf("Ready to rock as proxy '%s' and in local mode", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s' and in local mode\n", config.ProxyName) } else { log.Errorf("Ready to rock as proxy '%s'", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s'\n", config.ProxyName) } } else { log.Error("Ready to rock in local-only mode") fmt.Println("Ready to rock in local-only mode") } waitIndefinitely() log.Error("Shutting down") fmt.Println("") fmt.Println("Shutting down") return 0 }
// updateConfigFile opens the config file, adds any missing fields, // writes the config file back. func updateConfigFile(context *cli.Context) { config, configFilename, err := lib.GetConfig(context) if err != nil { log.Fatalln(err) } if configFilename == "" { fmt.Println("Could not find a config file to update") return } // Same config in []byte format. configRaw, err := ioutil.ReadFile(configFilename) if err != nil { log.Fatalln(err) } // Same config in map format so that we can detect missing keys. var configMap map[string]interface{} if err = json.Unmarshal(configRaw, &configMap); err != nil { log.Fatalln(err) } dirty := updateConfig(config, configMap) if dirty { config.ToFile(context) fmt.Printf("Wrote %s\n", configFilename) } else { fmt.Println("Nothing to update") } }
// getConfig returns a config object func getConfig(context *cli.Context) *lib.Config { config, _, err := lib.GetConfig(context) if err != nil { log.Fatalln(err) } return config }
// getConfig returns a config object func getConfig() *lib.Config { config, _, err := lib.GetConfig() if err != nil { panic(err) } return config }
func monitorConnector() { config, filename, err := lib.GetConfig() if err != nil { panic(fmt.Sprintf("Failed to read config file: %s", err)) } if filename == "" { fmt.Fprintln(os.Stderr, "No config file was found, so using defaults") } if _, err := os.Stat(config.MonitorSocketFilename); err != nil { if !os.IsNotExist(err) { panic(err) } panic(fmt.Sprintf( "No connector is running, or the monitoring socket %s is mis-configured", config.MonitorSocketFilename)) } timer := time.AfterFunc(*monitorTimeoutFlag, func() { panic(fmt.Sprintf("timeout after %s", monitorTimeoutFlag.String())) }) conn, err := net.DialTimeout("unix", config.MonitorSocketFilename, time.Second) if err != nil { panic(fmt.Sprintf( "No connector is running, or it is not listening to socket %s", config.MonitorSocketFilename)) } defer conn.Close() buf, err := ioutil.ReadAll(conn) if err != nil { panic(err) } timer.Stop() fmt.Printf(string(buf)) }
func monitorConnector(context *cli.Context) { config, filename, err := lib.GetConfig(context) if err != nil { log.Fatalf("Failed to read config file: %s\n", err) } if filename == "" { fmt.Println("No config file was found, so using defaults") } if _, err := os.Stat(config.MonitorSocketFilename); err != nil { if !os.IsNotExist(err) { log.Fatalln(err) } log.Fatalf( "No connector is running, or the monitoring socket %s is mis-configured\n", config.MonitorSocketFilename) } timer := time.AfterFunc(context.Duration("monitor-timeout"), func() { log.Fatalf("Timeout after %s\n", context.Duration("monitor-timeout").String()) }) conn, err := net.DialTimeout("unix", config.MonitorSocketFilename, time.Second) if err != nil { log.Fatalf( "No connector is running, or it is not listening to socket %s\n", config.MonitorSocketFilename) } defer conn.Close() buf, err := ioutil.ReadAll(conn) if err != nil { log.Fatalln(err) } timer.Stop() fmt.Printf(string(buf)) }
// updateConfigFile opens the config file, adds any missing fields, // writes the config file back. func updateConfigFile(context *cli.Context) { config, configFilename, err := lib.GetConfig(context) if err != nil { log.Fatalln(err) } if configFilename == "" { fmt.Println("Could not find a config file to update") return } // Same config in []byte format. configRaw, err := ioutil.ReadFile(configFilename) if err != nil { log.Fatalln(err) } // Same config in map format so that we can detect missing keys. var configMap map[string]interface{} if err = json.Unmarshal(configRaw, &configMap); err != nil { log.Fatalln(err) } // No changes detected yet. dirty := false if _, exists := configMap["gcp_max_concurrent_downloads"]; !exists { dirty = true fmt.Println("Added gcp_max_concurrent_downloads") config.GCPMaxConcurrentDownloads = lib.DefaultConfig.GCPMaxConcurrentDownloads } if _, exists := configMap["cups_max_connections"]; !exists { dirty = true fmt.Println("Added cups_max_connections") config.CUPSMaxConnections = lib.DefaultConfig.CUPSMaxConnections } if _, exists := configMap["cups_connect_timeout"]; !exists { dirty = true fmt.Println("Added cups_connect_timeout") config.CUPSConnectTimeout = lib.DefaultConfig.CUPSConnectTimeout } if _, exists := configMap["cups_job_queue_size"]; !exists { dirty = true fmt.Println("Added cups_job_queue_size") config.CUPSJobQueueSize = lib.DefaultConfig.CUPSJobQueueSize } if _, exists := configMap["cups_printer_poll_interval"]; !exists { dirty = true fmt.Println("Added cups_printer_poll_interval") config.CUPSPrinterPollInterval = lib.DefaultConfig.CUPSPrinterPollInterval } if _, exists := configMap["cups_printer_attributes"]; !exists { dirty = true fmt.Println("Added cups_printer_attributes") config.CUPSPrinterAttributes = lib.DefaultConfig.CUPSPrinterAttributes } else { // Make sure all required attributes are present. s := make(map[string]struct{}, len(config.CUPSPrinterAttributes)) for _, a := range config.CUPSPrinterAttributes { s[a] = struct{}{} } for _, a := range lib.DefaultConfig.CUPSPrinterAttributes { if _, exists := s[a]; !exists { dirty = true fmt.Printf("Added %s to cups_printer_attributes\n", a) config.CUPSPrinterAttributes = append(config.CUPSPrinterAttributes, a) } } } if _, exists := configMap["cups_job_full_username"]; !exists { dirty = true fmt.Println("Added cups_job_full_username") config.CUPSJobFullUsername = lib.DefaultConfig.CUPSJobFullUsername } if _, exists := configMap["cups_ignore_class_printers"]; !exists { dirty = true fmt.Println("Added cups_ignore_class_printers") config.CUPSIgnoreClassPrinters = lib.DefaultConfig.CUPSIgnoreClassPrinters } if _, exists := configMap["cups_ignore_raw_printers"]; !exists { dirty = true fmt.Println("Added cups_ignore_raw_printers") config.CUPSIgnoreRawPrinters = lib.DefaultConfig.CUPSIgnoreRawPrinters } if _, exists := configMap["copy_printer_info_to_display_name"]; !exists { dirty = true fmt.Println("Added copy_printer_info_to_display_name") config.CopyPrinterInfoToDisplayName = lib.DefaultConfig.CopyPrinterInfoToDisplayName } if _, exists := configMap["display_name_prefix"]; !exists { dirty = true fmt.Println("Added display_name_prefix") config.DisplayNamePrefix = lib.DefaultConfig.DisplayNamePrefix } if _, exists := configMap["monitor_socket_filename"]; !exists { dirty = true fmt.Println("Added monitor_socket_filename") config.MonitorSocketFilename = lib.DefaultConfig.MonitorSocketFilename } if _, exists := configMap["gcp_base_url"]; !exists { dirty = true fmt.Println("Added gcp_base_url") config.GCPBaseURL = lib.DefaultConfig.GCPBaseURL } if _, exists := configMap["xmpp_server"]; !exists { dirty = true fmt.Println("Added xmpp_server") config.XMPPServer = lib.DefaultConfig.XMPPServer } if _, exists := configMap["xmpp_port"]; !exists { dirty = true fmt.Println("Added xmpp_port") config.XMPPPort = lib.DefaultConfig.XMPPPort } if _, exists := configMap["gcp_xmpp_ping_timeout"]; !exists { dirty = true fmt.Println("Added gcp_xmpp_ping_timeout") config.XMPPPingTimeout = lib.DefaultConfig.XMPPPingTimeout } if _, exists := configMap["gcp_xmpp_ping_interval_default"]; !exists { dirty = true fmt.Println("Added gcp_xmpp_ping_interval_default") config.XMPPPingInterval = lib.DefaultConfig.XMPPPingInterval } if _, exists := configMap["gcp_oauth_client_id"]; !exists { dirty = true fmt.Println("Added gcp_oauth_client_id") config.GCPOAuthClientID = lib.DefaultConfig.GCPOAuthClientID } if _, exists := configMap["gcp_oauth_client_secret"]; !exists { dirty = true fmt.Println("Added gcp_oauth_client_secret") config.GCPOAuthClientSecret = lib.DefaultConfig.GCPOAuthClientSecret } if _, exists := configMap["gcp_oauth_auth_url"]; !exists { dirty = true fmt.Println("Added gcp_oauth_auth_url") config.GCPOAuthAuthURL = lib.DefaultConfig.GCPOAuthAuthURL } if _, exists := configMap["gcp_oauth_token_url"]; !exists { dirty = true fmt.Println("Added gcp_oauth_token_url") config.GCPOAuthTokenURL = lib.DefaultConfig.GCPOAuthTokenURL } if _, exists := configMap["snmp_enable"]; !exists { dirty = true fmt.Println("Added snmp_enable") config.SNMPEnable = lib.DefaultConfig.SNMPEnable } if _, exists := configMap["snmp_community"]; !exists { dirty = true fmt.Println("Added snmp_community") config.SNMPCommunity = lib.DefaultConfig.SNMPCommunity } if _, exists := configMap["snmp_max_connections"]; !exists { dirty = true fmt.Println("Added snmp_max_connections") config.SNMPMaxConnections = lib.DefaultConfig.SNMPMaxConnections } if _, exists := configMap["local_printing_enable"]; !exists { dirty = true fmt.Println("Added local_printing_enable") config.LocalPrintingEnable = lib.DefaultConfig.LocalPrintingEnable } if _, exists := configMap["cloud_printing_enable"]; !exists { dirty = true _, robot_token_exists := configMap["robot_refresh_token"] fmt.Println("Added cloud_printing_enable") if robot_token_exists { config.CloudPrintingEnable = true } else { config.CloudPrintingEnable = lib.DefaultConfig.CloudPrintingEnable } } if _, exists := configMap["log_file_name"]; !exists { dirty = true fmt.Println("Added log_file_name") config.LogFileName = lib.DefaultConfig.LogFileName } if _, exists := configMap["log_file_max_megabytes"]; !exists { dirty = true fmt.Println("Added log_file_max_megabytes") config.LogFileMaxMegabytes = lib.DefaultConfig.LogFileMaxMegabytes } if _, exists := configMap["log_max_files"]; !exists { dirty = true fmt.Println("Added log_max_files") config.LogMaxFiles = lib.DefaultConfig.LogMaxFiles } if _, exists := configMap["log_level"]; !exists { dirty = true fmt.Println("Added log_level") config.LogLevel = lib.DefaultConfig.LogLevel } if _, exists := configMap["log_to_journal"]; !exists { dirty = true fmt.Println("Added log_to_journal") config.LogToJournal = lib.DefaultConfig.LogToJournal } if _, exists := configMap["printer_blacklist"]; !exists { dirty = true fmt.Println("Added printer_blacklist") config.PrinterBlacklist = lib.DefaultConfig.PrinterBlacklist } if dirty { config.ToFile(context) fmt.Printf("Wrote %s\n", configFilename) } else { fmt.Println("Nothing to update") } }
func main() { flag.Parse() defer glog.Flush() glog.Error(lib.FullName) fmt.Println(lib.FullName) config, configFilename, err := lib.GetConfig() if err != nil { glog.Fatal(err) } if configFilename == "" { glog.Info("No config file was found, so using defaults") } if !config.CloudPrintingEnable && !config.LocalPrintingEnable { glog.Fatal("Cannot run connector with both local_printing_enable and cloud_printing_enable set to false") } if _, err := os.Stat(config.MonitorSocketFilename); !os.IsNotExist(err) { if err != nil { glog.Fatal(err) } glog.Fatalf( "A connector is already running, or the monitoring socket %s wasn't cleaned up properly", config.MonitorSocketFilename) } cupsConnectTimeout, err := time.ParseDuration(config.CUPSConnectTimeout) if err != nil { glog.Fatalf("Failed to parse cups connect timeout: %s", err) } gcpXMPPPingTimeout, err := time.ParseDuration(config.XMPPPingTimeout) if err != nil { glog.Fatalf("Failed to parse xmpp ping timeout: %s", err) } gcpXMPPPingIntervalDefault, err := time.ParseDuration(config.XMPPPingIntervalDefault) if err != nil { glog.Fatalf("Failed to parse xmpp ping interval default: %s", err) } jobs := make(chan *lib.Job, 10) xmppNotifications := make(chan xmpp.PrinterNotification, 5) var g *gcp.GoogleCloudPrint var x *xmpp.XMPP if config.CloudPrintingEnable { g, err = gcp.NewGoogleCloudPrint(config.GCPBaseURL, config.RobotRefreshToken, config.UserRefreshToken, config.ProxyName, config.GCPOAuthClientID, config.GCPOAuthClientSecret, config.GCPOAuthAuthURL, config.GCPOAuthTokenURL, config.GCPMaxConcurrentDownloads, jobs) if err != nil { glog.Fatal(err) } x, err = xmpp.NewXMPP(config.XMPPJID, config.ProxyName, config.XMPPServer, config.XMPPPort, gcpXMPPPingTimeout, gcpXMPPPingIntervalDefault, g.GetRobotAccessToken, xmppNotifications) if err != nil { glog.Fatal(err) } defer x.Quit() } c, err := cups.NewCUPS(config.CopyPrinterInfoToDisplayName, config.PrefixJobIDToJobTitle, config.DisplayNamePrefix, config.CUPSPrinterAttributes, config.CUPSMaxConnections, cupsConnectTimeout) if err != nil { glog.Fatal(err) } defer c.Quit() var s *snmp.SNMPManager if config.SNMPEnable { glog.Info("SNMP enabled") s, err = snmp.NewSNMPManager(config.SNMPCommunity, config.SNMPMaxConnections) if err != nil { glog.Fatal(err) } defer s.Quit() } var priv *privet.Privet if config.LocalPrintingEnable { if g == nil { priv, err = privet.NewPrivet(jobs, config.GCPBaseURL, nil) } else { priv, err = privet.NewPrivet(jobs, config.GCPBaseURL, g.ProximityToken) } if err != nil { glog.Fatal(err) } defer priv.Quit() } pm, err := manager.NewPrinterManager(c, g, priv, s, config.CUPSPrinterPollInterval, config.CUPSJobQueueSize, config.CUPSJobFullUsername, config.CUPSIgnoreRawPrinters, config.ShareScope, jobs, xmppNotifications) if err != nil { glog.Fatal(err) } defer pm.Quit() m, err := monitor.NewMonitor(c, g, priv, pm, config.MonitorSocketFilename) if err != nil { glog.Fatal(err) } defer m.Quit() if config.CloudPrintingEnable { if config.LocalPrintingEnable { glog.Errorf("Ready to rock as proxy '%s' and in local mode", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s' and in local mode\n", config.ProxyName) } else { glog.Errorf("Ready to rock as proxy '%s'", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s'\n", config.ProxyName) } } else { glog.Error("Ready to rock in local-only mode") fmt.Println("Ready to rock in local-only mode") } waitIndefinitely() glog.Error("Shutting down") fmt.Println("") fmt.Println("Shutting down") }
func connector(context *cli.Context) int { config, configFilename, err := lib.GetConfig(context) if err != nil { fmt.Fprintf(os.Stderr, "Failed to read config file: %s", err) return 1 } log.SetLogToConsole(context.Bool("log-to-console")) logLevel, ok := log.LevelFromString(config.LogLevel) if !ok { fmt.Fprintf(os.Stderr, "Log level %s is not recognized", config.LogLevel) return 1 } log.SetLevel(logLevel) if configFilename == "" { log.Info("No config file was found, so using defaults") } log.Info(lib.FullName) fmt.Println(lib.FullName) if !config.CloudPrintingEnable && !config.LocalPrintingEnable { log.Fatal("Cannot run connector with both local_printing_enable and cloud_printing_enable set to false") return 1 } else if config.LocalPrintingEnable { log.Fatal("Local printing has not been implemented in this version of the Windows connector.") return 1 } jobs := make(chan *lib.Job, 10) xmppNotifications := make(chan xmpp.PrinterNotification, 5) var g *gcp.GoogleCloudPrint var x *xmpp.XMPP if config.CloudPrintingEnable { xmppPingTimeout, err := time.ParseDuration(config.XMPPPingTimeout) if err != nil { log.Fatalf("Failed to parse xmpp ping timeout: %s", err) return 1 } xmppPingInterval, err := time.ParseDuration(config.XMPPPingInterval) if err != nil { log.Fatalf("Failed to parse xmpp ping interval default: %s", err) return 1 } g, err = gcp.NewGoogleCloudPrint(config.GCPBaseURL, config.RobotRefreshToken, config.UserRefreshToken, config.ProxyName, config.GCPOAuthClientID, config.GCPOAuthClientSecret, config.GCPOAuthAuthURL, config.GCPOAuthTokenURL, config.GCPMaxConcurrentDownloads, jobs) if err != nil { log.Fatal(err) return 1 } x, err = xmpp.NewXMPP(config.XMPPJID, config.ProxyName, config.XMPPServer, config.XMPPPort, xmppPingTimeout, xmppPingInterval, g.GetRobotAccessToken, xmppNotifications) if err != nil { log.Fatal(err) return 1 } defer x.Quit() } ws, err := winspool.NewWinSpool(config.PrefixJobIDToJobTitle, config.DisplayNamePrefix, config.PrinterBlacklist) if err != nil { log.Fatal(err) return 1 } nativePrinterPollInterval, err := time.ParseDuration(config.NativePrinterPollInterval) if err != nil { log.Fatalf("Failed to parse printer poll interval: %s", err) return 1 } pm, err := manager.NewPrinterManager(ws, g, nil, nil, nativePrinterPollInterval, config.NativeJobQueueSize, false, false, config.ShareScope, jobs, xmppNotifications) if err != nil { log.Fatal(err) return 1 } defer pm.Quit() if config.CloudPrintingEnable { if config.LocalPrintingEnable { log.Infof("Ready to rock as proxy '%s' and in local mode", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s' and in local mode\n", config.ProxyName) } else { log.Infof("Ready to rock as proxy '%s'", config.ProxyName) fmt.Printf("Ready to rock as proxy '%s'\n", config.ProxyName) } } else { log.Info("Ready to rock in local-only mode") fmt.Println("Ready to rock in local-only mode") } waitIndefinitely() log.Info("Shutting down") fmt.Println("") fmt.Println("Shutting down") return 0 }