//export handleGroupStateChange func handleGroupStateChange(group *C.AvahiEntryGroup, state C.AvahiEntryGroupState, name unsafe.Pointer) { switch state { case C.AVAHI_ENTRY_GROUP_COLLISION: log.Warningf("Avahi failed to register %s due to a naming collision", C.GoString((*C.char)(name))) case C.AVAHI_ENTRY_GROUP_FAILURE: log.Warningf("Avahi failed to register %s, don't know why", C.GoString((*C.char)(name))) } }
func (api *privetAPI) createjob(w http.ResponseWriter, r *http.Request) { log.Debugf("Received /createjob request: %+v", r) if ok := api.checkRequest(w, r, "POST"); !ok { return } requestBody, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("Failed to read request body: %s", err) writeError(w, "invalid_ticket", "Check connector logs") return } var ticket cdd.CloudJobTicket if err = json.Unmarshal(requestBody, &ticket); err != nil { log.Warningf("Failed to read request body: %s", err) writeError(w, "invalid_ticket", "Check connector logs") return } printer, exists := api.getPrinter(api.name) if !exists { w.WriteHeader(http.StatusInternalServerError) return } if printer.State.State == cdd.CloudDeviceStateStopped { writeError(w, "printer_error", "Printer is stopped") return } jobID, expiresIn := api.jc.createJob(&ticket) var response struct { JobID string `json:"job_id"` ExpiresIn int32 `json:"expires_in"` } response.JobID = jobID response.ExpiresIn = expiresIn j, err := json.MarshalIndent(response, "", " ") if err != nil { api.jc.deleteJob(jobID) log.Errorf("Failed to marrshal createJob response: %s", err) w.WriteHeader(http.StatusInternalServerError) } else { w.Write(j) } }
func (pm *PrinterManager) syncPrinters(ignorePrivet bool) error { log.Info("Synchronizing printers, stand by") // Get current snapshot of CUPS printers. cupsPrinters, err := pm.cups.GetPrinters() if err != nil { return fmt.Errorf("Sync failed while calling GetPrinters(): %s", err) } if pm.ignoreRawPrinters { cupsPrinters, _ = lib.FilterRawPrinters(cupsPrinters) } // Augment CUPS printers with extra information from SNMP. if pm.snmp != nil { err = pm.snmp.AugmentPrinters(cupsPrinters) if err != nil { log.Warningf("Failed to augment printers with SNMP data: %s", err) } } // Set CapsHash on all printers. for i := range cupsPrinters { h := adler32.New() lib.DeepHash(cupsPrinters[i].Tags, h) cupsPrinters[i].Tags["tagshash"] = fmt.Sprintf("%x", h.Sum(nil)) h = adler32.New() lib.DeepHash(cupsPrinters[i].Description, h) cupsPrinters[i].CapsHash = fmt.Sprintf("%x", h.Sum(nil)) } // Compare the snapshot to what we know currently. diffs := lib.DiffPrinters(cupsPrinters, pm.printers.GetAll()) if diffs == nil { log.Infof("Printers are already in sync; there are %d", len(cupsPrinters)) return nil } // Update GCP. ch := make(chan lib.Printer, len(diffs)) for i := range diffs { go pm.applyDiff(&diffs[i], ch, ignorePrivet) } currentPrinters := make([]lib.Printer, 0, len(diffs)) for _ = range diffs { p := <-ch if p.Name != "" { currentPrinters = append(currentPrinters, p) } } // Update what we know. pm.printers.Refresh(currentPrinters) log.Infof("Finished synchronizing %d printers", len(currentPrinters)) return nil }
func (m *Monitor) listen(listener net.Listener) { ch := make(chan net.Conn) quitReq := make(chan bool, 1) quitAck := make(chan bool) go func() { for { conn, err := listener.Accept() if err != nil { select { case <-quitReq: quitAck <- true return } log.Errorf("Error listening to monitor socket: %s", err) } else { ch <- conn } } }() for { select { case conn := <-ch: log.Info("Received monitor request") stats, err := m.getStats() if err != nil { log.Warningf("Monitor request failed: %s", err) conn.Write([]byte("error")) } else { conn.Write([]byte(stats)) } conn.Close() case <-m.listenerQuit: quitReq <- true listener.Close() <-quitAck m.listenerQuit <- true return } } }
// dispatchIncoming listens for new XMPP notifications and puts them into // separate channels, by type of message. func (x *internalXMPP) dispatchIncoming(dying chan<- struct{}) { for { // The xml.StartElement tells us what is coming up. startElement, err := readStartElement(x.xmlDecoder) if err != nil { if isXMLErrorClosedConnection(err) { break } log.Errorf("Failed to read the next start element: %s", err) break } // Parse the message. if startElement.Name.Local == "message" { var message struct { XMLName xml.Name `xml:"message"` Data string `xml:"push>data"` } if err := x.xmlDecoder.DecodeElement(&message, startElement); err != nil { if isXMLErrorClosedConnection(err) { break } log.Warningf("Error while parsing print jobs notification via XMPP: %s", err) continue } messageData, err := base64.StdEncoding.DecodeString(message.Data) if err != nil { log.Warningf("Failed to convert XMPP message data from base64: %s", err) continue } messageDataString := string(messageData) if strings.ContainsRune(messageDataString, '/') { if strings.HasSuffix(messageDataString, "/delete") { gcpID := strings.TrimSuffix(messageDataString, "/delete") x.notifications <- PrinterNotification{gcpID, PrinterDelete} } // Ignore other suffixes, like /update_settings. } else { x.notifications <- PrinterNotification{messageDataString, PrinterNewJobs} } } else if startElement.Name.Local == "iq" { var message struct { XMLName xml.Name `xml:"iq"` ID string `xml:"id,attr"` Type string `xml:"type,attr"` } if err := x.xmlDecoder.DecodeElement(&message, startElement); err != nil { if isXMLErrorClosedConnection(err) { break } log.Warningf("Error while parsing XMPP pong: %s", err) continue } pingID, err := strconv.ParseUint(message.ID, 10, 8) if err != nil { log.Warningf("Failed to convert XMPP ping ID: %s", err) continue } x.pongs <- uint8(pingID) } else { log.Warningf("Unexpected element while waiting for print message: %+v", startElement) } } dying <- struct{}{} }
//export logBonjourError func logBonjourError(err *C.char) { log.Warningf("Bonjour: %s", C.GoString(err)) }
// convertMarkers converts CUPS marker-(names|types|levels) to *[]cdd.Marker and *cdd.MarkerState. // // Normalizes marker type: toner(Cartridge|-cartridge) => toner, // ink(Cartridge|-cartridge|Ribbon|-ribbon) => ink func convertMarkers(printerTags map[string][]string) (*[]cdd.Marker, *cdd.MarkerState) { names, types, levels := printerTags[attrMarkerNames], printerTags[attrMarkerTypes], printerTags[attrMarkerLevels] if len(names) == 0 || len(types) == 0 || len(levels) == 0 { return nil, nil } if len(names) != len(levels) { newNames := fixMarkers(names) if len(newNames) != len(levels) { log.Warningf("Received badly-formatted marker-names from CUPS: %s, %s, %s", strings.Join(names, ";"), strings.Join(types, ";"), strings.Join(levels, ";")) return nil, nil } names = newNames } { nameSet := make(map[string]struct{}, len(names)) for _, name := range names { if _, exists := nameSet[name]; exists { return nil, nil } nameSet[name] = struct{}{} } } if len(types) != len(levels) { newTypes := fixMarkers(types) if len(newTypes) != len(levels) { log.Warningf("Received badly-formatted marker-types from CUPS: %s, %s, %s", strings.Join(names, ";"), strings.Join(types, ";"), strings.Join(levels, ";")) return nil, nil } types = newTypes } markers := make([]cdd.Marker, 0, len(names)) states := cdd.MarkerState{make([]cdd.MarkerStateItem, 0, len(names))} for i := 0; i < len(names); i++ { if len(names[i]) == 0 { return nil, nil } var markerType cdd.MarkerType switch strings.ToLower(types[i]) { case "toner", "tonercartridge", "toner-cartridge": markerType = cdd.MarkerToner case "ink", "inkcartridge", "ink-cartridge", "ink-ribbon", "inkribbon": markerType = cdd.MarkerInk case "staples": markerType = cdd.MarkerStaples default: continue } var color *cdd.MarkerColor if markerType == cdd.MarkerToner || markerType == cdd.MarkerInk { nameStripped := strings.Replace(strings.Replace(strings.ToLower(names[i]), " ", "", -1), "-", "", -1) colorType := cdd.MarkerColorCustom for k, v := range cupsMarkerNameToGCP { if strings.HasPrefix(nameStripped, k) { colorType = v break } } color = &cdd.MarkerColor{Type: colorType} if colorType == cdd.MarkerColorCustom { name := names[i] name = strings.TrimSuffix(name, " Cartridge") name = strings.TrimSuffix(name, " cartridge") name = strings.TrimSuffix(name, " Ribbon") name = strings.TrimSuffix(name, " ribbon") name = strings.TrimSuffix(name, " Toner") name = strings.TrimSuffix(name, " toner") name = strings.TrimSuffix(name, " Ink") name = strings.TrimSuffix(name, " ink") name = strings.Replace(name, "-", " ", -1) color.CustomDisplayNameLocalized = cdd.NewLocalizedString(name) } } marker := cdd.Marker{ VendorID: names[i], Type: markerType, Color: color, } level, err := strconv.ParseInt(levels[i], 10, 32) if err != nil { log.Warningf("Failed to parse CUPS marker state %s=%s: %s", names[i], levels[i], err) return nil, nil } if level > 100 { // Lop off extra (proprietary?) bits. level = level & 0x7f } if level < 0 || level > 100 { return nil, nil } var state cdd.MarkerStateType if level > 10 { state = cdd.MarkerStateOK } else { state = cdd.MarkerStateExhausted } level32 := int32(level) markerState := cdd.MarkerStateItem{ VendorID: names[i], State: state, LevelPercent: &level32, } markers = append(markers, marker) states.Item = append(states.Item, markerState) } return &markers, &states }