char *dateHuman(char *a, char *b, char *c, const char *LOCAL_no_date_set) { // This will need to be converted, to use current users 'lang' LOCALE char *m; if( 0 != strcmp(a, "NULL") && 0 != strcmp(b, "NULL") && 0 != strcmp(c, "NULL")) { if(strlen(b) == 1) { m = o_strdup("0"); conCat(&m, b); free(b); b = m; } if(strlen(c) == 1) { m = o_strdup("0"); conCat(&m, c); free(c); c = m; } conCat(&a, "/"); conCat(&a, b); conCat(&a, "/"); conCat(&a, c); free(b); free(c); return a; } else { free(a); free(b); free(c); return o_strdup(LOCAL_no_date_set); } }
extern char *getTagId(char *tagname) { struct simpleLinkedList *vars, *rSet; char *sql2, *ret = NULL; char *sql = o_printf("SELECT tagid FROM tags WHERE tagname = '%s'", tagname); rSet = runquery_db(sql); if( rSet != NULL ) { ret = o_strdup(readData_db(rSet, "tagid")); } else { o_log(DEBUGM, "no tag was found. Adding a new one."); sql2 = o_strdup("INSERT INTO tags (tagname) VALUES (?)"); vars = sll_init(); sll_append(vars, DB_TEXT ); sll_append(vars, tagname ); runUpdate_db(sql2, vars); free(sql2); ret = itoa(last_insert(), 10); } free_recordset( rSet ); free(sql); o_log(DEBUGM, "Using tagid of %s", ret); return ret; }
// Create a new session // FIXME - This is currently open to a DoS attack. // but since we have a session limit, just for opendias. char *create_session() { char *session_id; // Check upper session count limit int current_session_count = sll_count( sll_findFirstElement( sessions ) ); o_log( DEBUGM, "There are currently %d active sessions", current_session_count); if( current_session_count > MAX_SESSIONS ) { return NULL; } // Generate session key uuid_t uu; char *sid = malloc(36+1); uuid_generate(uu); uuid_unparse(uu, sid); session_id = o_strdup(sid); free(sid); o_log(DEBUGM, "Generated new session: %s", session_id ); // Create new session structure struct session_data *session_element = malloc( sizeof(struct session_data) ); session_element->last_accessed = time(NULL); session_element->session_container = sll_init(); // Save and return sll_insert( sessions, o_strdup(session_id), session_element ); return session_id; }
void addFileExt(char **fname, int ftype) { char *ext; if(ftype == SCAN_FILETYPE) ext = o_strdup(".jpg"); else if(ftype == PDF_FILETYPE) ext = o_strdup(".pdf"); else if(ftype == ODF_FILETYPE) ext = o_strdup(".odt"); else if(ftype == JPG_FILETYPE) ext = o_strdup(".jpg"); else ext = o_strdup(".WILLNEVERHAPPEN"); conCat(fname, ext); free(ext); }
extern const char *get_status_string (SANE_Status status) { struct { SANE_Status status; const char *name; } status_names[] = { { SANE_STATUS_GOOD, "SANE_STATUS_GOOD"}, { SANE_STATUS_UNSUPPORTED, "SANE_STATUS_UNSUPPORTED"}, { SANE_STATUS_CANCELLED, "SANE_STATUS_CANCELLED"}, { SANE_STATUS_DEVICE_BUSY, "SANE_STATUS_DEVICE_BUSY"}, { SANE_STATUS_INVAL, "SANE_STATUS_INVAL"}, { SANE_STATUS_EOF, "SANE_STATUS_EOF"}, { SANE_STATUS_JAMMED, "SANE_STATUS_JAMMED"}, { SANE_STATUS_NO_DOCS, "SANE_STATUS_NO_DOCS"}, { SANE_STATUS_COVER_OPEN, "SANE_STATUS_COVER_OPEN"}, { SANE_STATUS_IO_ERROR, "SANE_STATUS_IO_ERROR"}, { SANE_STATUS_NO_MEM, "SANE_STATUS_NO_MEM"}, { SANE_STATUS_ACCESS_DENIED, "SANE_STATUS_ACCESS_DENIED"}, { -1, NULL} }; static char *unknown_string = NULL; int i; for (i = 0; status_names[i].name != NULL && status_names[i].status != status; i++); if (status_names[i].name == NULL) { free (unknown_string); unknown_string = o_strdup(""); o_concatf (&unknown_string, "SANE_ACTION(%d)", status); return unknown_string; /* Note result is undefined on second call to this function */ } return status_names[i].name; }
/** * Check if all mandatory configuration parameters are present and correct * Initialize some parameters with default value if not set */ int check_config(struct config_elements * config) { if (config->instance->port == 1) { config->instance->port = GARETH_DEFAULT_PORT; } if (config->url_prefix == NULL) { config->url_prefix = o_strdup(GARETH_DEFAULT_PREFIX); if (config->url_prefix == NULL) { fprintf(stderr, "Error allocating url_prefix, exit\n"); return 0; } } if (config->log_mode == Y_LOG_MODE_NONE) { config->log_mode = Y_LOG_MODE_CONSOLE; } if (config->log_level == Y_LOG_LEVEL_NONE) { config->log_level = Y_LOG_LEVEL_ERROR; } if (config->log_mode == Y_LOG_MODE_FILE && config->log_file == NULL) { fprintf(stderr, "Error, you must specify a log file if log mode is set to file\n"); print_help(stderr); return 0; } return 1; }
void ocrImage( char *uuid, int docid, int page, int request_resolution, PIX *pix, char *lang ) { char *ocrText; char *ocrLang; ocrLang = getScanParam(uuid, SCAN_PARAM_DO_OCR); #ifdef CAN_OCR if(ocrLang && 0 != strcmp(ocrLang, "-") ) { if(request_resolution >= 300 && request_resolution <= 400) { char *ocrScanText; o_log(INFORMATION, "Attempting OCR in lang of %s", ocrLang); updateScanProgress(uuid, SCAN_PERFORMING_OCR, 10); ocrScanText = getTextFromImage(pix, request_resolution, ocrLang); ocrText = o_printf( getString("LOCAL_page_delimiter", lang), page, ocrScanText); free(ocrScanText); } else { o_log(DEBUGM, "OCR was requested, but the specified resolution means it's not safe to be attempted"); ocrText = o_printf( getString("LOCAL_resolution_outside_range_to_attempt_ocr", lang) ); } } else #endif /* CAN_OCR */ ocrText = o_strdup(""); free(ocrLang); updateScanProgress(uuid, SCAN_DB_WORKING, 0); updateNewScannedPage(docid, ocrText, page); free(ocrText); }
extern void removeDoc (char *docid) { char *sql = o_strdup("DELETE FROM docs WHERE docid = ?"); int docid_i = atoi(docid); struct simpleLinkedList *vars = sll_init(); sll_append(vars, DB_INT ); sll_append(vars, &docid_i ); runUpdate_db(sql, vars); free(sql); }
extern void deleteTag( char *tagid ) { char *sql = o_strdup("DELETE FROM tags WHERE tagid = ?"); int tagid_i = atoi(tagid); struct simpleLinkedList *vars = sll_init(); sll_append(vars, DB_INT ); sll_append(vars, &tagid_i ); runUpdate_db(sql, vars); free(sql); }
extern void addLocation(char *location, int role) { char *sql = o_strdup("INSERT INTO location_access (location, role) VALUES (?, ?);"); struct simpleLinkedList *vars = sll_init(); sll_append(vars, DB_TEXT ); sll_append(vars, location ); sll_append(vars, DB_INT ); sll_append(vars, &role ); runUpdate_db(sql, vars); free(sql); }
void sane_worker( char *command, char *param ) { char *response; if( SANE_STATUS_GOOD != sane_init(NULL, NULL) ) { o_log( ERROR, "Could not start sane"); } // Get a list of scanners if ( command && 0 == strcmp(command, "internalGetScannerList") ) { response = internalGetScannerList( param ); } // Get scanner details (attributes) else if ( command && 0 == strcmp(command, "internalGetScannerDetails") ) { char *deviceid = strtok(o_strdup(param), ","); // device char *lang = strtok( NULL, ","); // lang response = internalGetScannerDetails( deviceid, lang ); free( deviceid ); } // Scan a page else if ( command && 0 == strcmp(command, "internalDoScanningOperation") ) { char *uuid = strtok(o_strdup(param), ","); // uuid char *lang = strtok( NULL, ","); // lang response = internalDoScanningOperation( uuid, lang ); free( uuid ); } else { o_log( ERROR, "Unknown Command"); response = o_strdup("ERROR"); } sane_exit(); // POST RESPONSE ON STDOUT printf("%s", response); free(response); }
char *xmlToText(char *xml, size_t size) { char *text = o_strdup(""); xmlDocPtr doc = xmlParseMemory(xml, (int)size); xmlNodePtr root = xmlDocGetRootElement(doc); xmlAllNodeGetContent(root, &text); xmlFreeDoc(doc); xmlCleanupParser(); return text; }
char *extractThumbnail(char *docid) { char *source_file, *target_file, *ocrText; source_file = o_printf("%s/scans/%s.pdf", BASE_DIR, docid); target_file = o_printf("%s/scans/%s_thumb.jpg", BASE_DIR, docid); ocrText = parse_pdf( source_file, target_file ); // pdf_plug.cc [create thumbnail and return body text] free(ocrText); free(source_file); free(target_file); return o_strdup("<?xml version='1.0' encoding='utf-8'?>\n<Response><RegenerateThumb><result>OK</result></RegenerateThumb></Response>"); }
extern void addScanProgress (char *uuid) { char *sql = o_strdup("INSERT INTO scan_progress (client_id, status, value) VALUES (?, ?, 0);"); int t1 = SCAN_IDLE; int *t = &t1; struct simpleLinkedList *vars = sll_init(); sll_append(vars, DB_TEXT ); sll_append(vars, uuid ); sll_append(vars, DB_INT ); sll_append(vars, t ); runUpdate_db(sql, vars); free(sql); }
extern void updateNewScannedPage (int docid, char *ocrText, int page) { char *sql = o_strdup("UPDATE docs SET pages = ?, ocrText = ocrText || ? WHERE docid = ?"); struct simpleLinkedList *vars = sll_init(); sll_append(vars, DB_INT ); sll_append(vars, &page ); sll_append(vars, DB_TEXT ); sll_append(vars, ocrText ); sll_append(vars, DB_INT ); sll_append(vars, &docid ); runUpdate_db(sql, vars); free(sql); }
char *get_odf_Text (const char *filename) { char *text; char *xml; size_t size; size = getEntry(filename, "content.xml", &xml); o_log(DEBUGM, "Found message of size %d. Message reads\n %s", size, xml); if(size > 0) { text = xmlToText(xml, size); } else { text = o_strdup(""); } free(xml); return text; }
extern char *getScanParam(char *scanid, int param_option) { char *sql, *vvalue = NULL; struct simpleLinkedList *rSet; sql = o_printf("SELECT param_value \ FROM scan_params \ WHERE client_id = '%s' \ AND param_option = %i", scanid, param_option); rSet = runquery_db(sql); if( rSet ) { vvalue = o_strdup(readData_db(rSet, "param_value")); } free_recordset( rSet ); free(sql); return vvalue; }
void update_config_option( char *option, char *value ) { char *sql = o_strdup("update config SET config_value = ? WHERE config_option = ?"); struct simpleLinkedList *vars = sll_init(); o_log(DEBUGM,"entering update_config_option\n"); sll_append(vars, DB_TEXT ); sll_append(vars, value ); sll_append(vars, DB_TEXT ); sll_append(vars, option ); o_log(INFORMATION, "|Attempting to set config option '%s' to '%s'", option, value); if( runUpdate_db(sql, vars) ) { o_log(INFORMATION, "| Failed!"); } else { o_log(INFORMATION, "| Successful."); } free(sql); o_log(DEBUGM,"leaving update_config_option\n"); }
extern const char *get_action_string (SANE_Action action) { struct { SANE_Action action; const char *name; } action_names[] = { { SANE_ACTION_GET_VALUE, "SANE_ACTION_GET_VALUE" }, { SANE_ACTION_SET_VALUE, "SANE_ACTION_SET_VALUE" }, { SANE_ACTION_SET_AUTO, "SANE_ACTION_SET_AUTO" }, { -1, NULL} }; static char *unknown_string = NULL; int i; for (i = 0; action_names[i].name != NULL && action_names[i].action != action; i++); if (action_names[i].name == NULL) { free (unknown_string); unknown_string = o_strdup(""); o_concatf (&unknown_string, "SANE_ACTION(%d)", action); return unknown_string; /* Note result is undefined on second call to this function */ } return action_names[i].name; }
extern SANE_Status control_option (SANE_Handle handle, const SANE_Option_Descriptor *option, SANE_Int index, SANE_Action action, void *value, int *ret) { SANE_Status status; char *old_value; switch (option->type) { case SANE_TYPE_BOOL: old_value = o_printf (*((SANE_Bool *) value) ? "SANE_TRUE" : "SANE_FALSE"); break; case SANE_TYPE_INT: old_value = o_printf ("%d", *((SANE_Int *) value)); break; case SANE_TYPE_FIXED: old_value = o_printf ("%f", SANE_UNFIX (*((SANE_Fixed *) value))); break; case SANE_TYPE_STRING: old_value = o_printf ("\"%s\"", (char *) value); break; default: old_value = o_strdup ("?"); break; } status = sane_control_option (handle, index, action, value, ret); switch (option->type) { case SANE_TYPE_BOOL: o_log(DEBUGM, "sane_control_option (%d, %s, %s) -> (%s, %s)", index, get_action_string (action), *((SANE_Bool *) value) ? "SANE_TRUE" : "SANE_FALSE", get_status_string (status), old_value); break; case SANE_TYPE_INT: o_log(DEBUGM, "sane_control_option (%d, %s, %d) -> (%s, %s)", index, get_action_string (action), *((SANE_Int *) value), get_status_string (status), old_value); break; case SANE_TYPE_FIXED: o_log(DEBUGM, "sane_control_option (%d, %s, %f) -> (%s, %s)", index, get_action_string (action), SANE_UNFIX (*((SANE_Fixed *) value)), get_status_string (status), old_value); break; case SANE_TYPE_STRING: o_log(DEBUGM, "sane_control_option (%d, %s, \"%s\") -> (%s, %s)", index, get_action_string (action), (char *) value, get_status_string (status), old_value); break; default: break; } free (old_value); if (status != SANE_STATUS_GOOD) o_log(WARNING, "Error setting option %s: %s", option->name, sane_strstatus(status)); return status; }
extern void log_option (SANE_Int index, const SANE_Option_Descriptor *option) { char *string; SANE_Word i; SANE_Int cap; string = o_strdup(""); o_concatf (&string, "Option %d:", index); if (option->name) o_concatf (&string, " name='%s'", option->name); if (option->title) o_concatf (&string, " title='%s'", option->title); switch (option->type) { case SANE_TYPE_BOOL: conCat(&string, " type=bool"); break; case SANE_TYPE_INT: conCat(&string, " type=int"); break; case SANE_TYPE_FIXED: conCat(&string, " type=fixed"); break; case SANE_TYPE_STRING: conCat(&string, " type=string"); break; case SANE_TYPE_BUTTON: conCat(&string, " type=button"); break; case SANE_TYPE_GROUP: conCat(&string, " type=group"); break; default: o_concatf (&string, " type=%d", option->type); break; } o_concatf (&string, " size=%d", option->size); switch (option->unit) { case SANE_UNIT_NONE: break; case SANE_UNIT_PIXEL: conCat(&string, " unit=pixels"); break; case SANE_UNIT_BIT: conCat(&string, " unit=bits"); break; case SANE_UNIT_MM: conCat(&string, " unit=mm"); break; case SANE_UNIT_DPI: conCat(&string, " unit=dpi"); break; case SANE_UNIT_PERCENT: conCat(&string, " unit=percent"); break; case SANE_UNIT_MICROSECOND: conCat(&string, " unit=microseconds"); break; default: o_concatf (&string, " unit=%d", option->unit); break; } switch (option->constraint_type) { case SANE_CONSTRAINT_RANGE: if (option->type == SANE_TYPE_FIXED) o_concatf (&string, " min=%f, max=%f, quant=%d", SANE_UNFIX (option->constraint.range->min), SANE_UNFIX (option->constraint.range->max), option->constraint.range->quant); else o_concatf (&string, " min=%d, max=%d, quant=%d", option->constraint.range->min, option->constraint.range->max, option->constraint.range->quant); break; case SANE_CONSTRAINT_WORD_LIST: conCat(&string, " values=["); for (i = 0; i < option->constraint.word_list[0]; i++) { if (i != 0) conCat(&string, ", "); if (option->type == SANE_TYPE_INT) o_concatf (&string, "%d", option->constraint.word_list[i+1]); else o_concatf (&string, "%f", SANE_UNFIX (option->constraint.word_list[i+1])); } conCat(&string, "]"); break; case SANE_CONSTRAINT_STRING_LIST: conCat(&string, " values=["); for (i = 0; option->constraint.string_list[i]; i++) { if (i != 0) conCat(&string, ", "); o_concatf (&string, "\"%s\"", option->constraint.string_list[i]); } conCat(&string, "]"); break; default: break; } cap = option->cap; if (cap) { struct { SANE_Int cap; const char *name; } caps[] = { { SANE_CAP_SOFT_SELECT, "soft-select"}, { SANE_CAP_HARD_SELECT, "hard-select"}, { SANE_CAP_SOFT_DETECT, "soft-detect"}, { SANE_CAP_EMULATED, "emulated"}, { SANE_CAP_AUTOMATIC, "automatic"}, { SANE_CAP_INACTIVE, "inactive"}, { SANE_CAP_ADVANCED, "advanced"}, { 0, NULL} }; int i, n = 0; conCat(&string, " cap="); for (i = 0; caps[i].cap > 0; i++) { if (cap & caps[i].cap) { cap &= ~caps[i].cap; if (n != 0) conCat(&string, ","); conCat(&string, caps[i].name); n++; } } /* Unknown capabilities */ if (cap) { if (n != 0) conCat(&string, ","); o_concatf (&string, "%x", cap); } } o_log(DEBUGM, "%s", string); free(string); // if (option->desc) // o_log(DEBUGM, " Description: %s", option->desc); }
void *backpopulate_phash_inner( void *u) { pthread_t thread[MAX_THREADS]; pthread_attr_t attr; int thread_pointer = 0; int avail_processors = 1; // We may have 16 processing cors, but only use what we need avail_processors = get_nprocs() - 1; if( avail_processors > MAX_THREADS ) { avail_processors = MAX_THREADS; } // initialise threading pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for( thread_pointer = 0; thread_pointer < MAX_THREADS; thread_pointer++ ) { pthread_create( &thread[ thread_pointer], &attr, stub, (void *)NULL ); } thread_pointer = 0; // What tasks do we need to do struct simpleLinkedList *rSet; char *sql = o_strdup("SELECT filetype, docid FROM docs WHERE image_phash = 0"); rSet = runquery_db(sql, NULL); if( rSet != NULL ) { do { // Queue up the next task int docid = atoi( readData_db(rSet, "docid") ); char *docfilename; if( ( 0 == strcmp("2", readData_db(rSet, "filetype") ) ) || ( 0 == strcmp("4", readData_db(rSet, "filetype") ) ) ) { docfilename = o_printf("%s/scans/%d_1.jpg", BASE_DIR, docid); } else { docfilename = o_printf("%s/scans/%d_thumb.jpg", BASE_DIR, docid); } // Wait for an available worker while( thread_active[thread_pointer] == 1 ) { thread_pointer++; if( thread_pointer > avail_processors ) { thread_pointer = 0; } usleep(200); } // Wait for it to join back first pthread_join( thread[ thread_pointer ], NULL); // Give instructions to the next worker struct process_phash *data = malloc( sizeof( struct process_phash ) ); data->filename = docfilename; data->docid = docid; data->thread_id = thread_pointer; thread_active[thread_pointer] = 1; pthread_create( &thread[ thread_pointer], &attr, process_doc, (void *)data ); } while ( nextRow( rSet ) ); free_recordset( rSet ); } free(sql); // Wait for everything t ofinish for( thread_pointer = 0; thread_pointer < MAX_THREADS; thread_pointer++ ) { pthread_join( thread[ thread_pointer ], NULL); } // Set the config flag, so we don't try this again. o_log(INFORMATION, "Marking that the backpopulation of pHash is: complete" ); sql = o_strdup("UPDATE config SET config_value = 'complete' WHERE config_option = 'backpopulate_phash'"); runUpdate_db(sql, NULL); free(sql); return NULL; }
char *internalDoScanningOperation(char *uuid, char *lang) { int request_resolution = 0; int docid; int current_page = 0; int total_requested_pages; double totbytes = 0; SANE_Status status; SANE_Handle *openDeviceHandle; SANE_Byte *raw_image; SANE_Parameters pars; char *docid_s; char *total_requested_pages_s; char *devName; char *outFilename; char *raw_image_format; char *header; o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid); updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0); // Open the device devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); o_log(DEBUGM, "sane_open of \"%s\"",devName); status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { handleSaneErrors("Cannot open device ", devName, status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); free(devName); return 0; } free(devName); /* ========================================================== */ if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) ) return 0; o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution); int timeout = 5; while( 0 < timeout ) { status = sane_start (openDeviceHandle); if(status == SANE_STATUS_GOOD) { break; } else { if(status == SANE_STATUS_DEVICE_BUSY ) { // BUSY signal could be the scanner just having a // bit of lag - specially network connected devices timeout--; if ( timeout == 0 ) { handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } else { o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout); usleep(500 * 1000); // 500ms or 0.5sec } } else { handleSaneErrors("Cannot start scanning", "", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } } } // Get scanning params (from the scanner) if( request_resolution == 0 ) { o_log(DEBUGM, "Resolution did not get set in scanner setup."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004); return 0; } o_log(DEBUGM, "Get scanning params"); status = sane_get_parameters (openDeviceHandle, &pars); o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d", sane_strstatus (status), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); switch (pars.format) { case SANE_FRAME_GRAY: o_log(DEBUGM, "Expecting Gray data (1 channel only)."); raw_image_format = o_strdup( "P5" ); break; case SANE_FRAME_RGB: o_log(DEBUGM, "Expecting RGB data (3 channels)."); raw_image_format = o_strdup( "P6" ); break; default: o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003); return 0; break; } header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", raw_image_format, pars.pixels_per_line, pars.lines, (pars.depth <= 8) ? 255 : 65535); free( raw_image_format ); // Save Record // docid_s = getScanParam(uuid, SCAN_PARAM_DOCID); total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES); total_requested_pages = atoi(total_requested_pages_s); free(total_requested_pages_s); if( docid_s == NULL ) { o_log(DEBUGM, "Saving record"); updateScanProgress(uuid, SCAN_DB_WORKING, 0); docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); setScanParam(uuid, SCAN_PARAM_DOCID, docid_s); setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1"); current_page = 1; } else { char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE); current_page = atoi(current_page_s); free(current_page_s); current_page++; current_page_s = itoa(current_page, 10); setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s); free(current_page_s); } docid = atoi(docid_s); free(docid_s); totbytes = (double)((pars.bytes_per_line * pars.lines)); /* ========================================================== */ raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header ); o_log(INFORMATION, "Scanning done."); o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // Convert Raw into JPEG // updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0); PIX *pix; if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) { o_log(ERROR, "Could not load the image data into a PIX"); } updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55); o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix)); free(raw_image); free(header); outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page); pixWrite(outFilename, pix, IFF_JFIF_JPEG); free(outFilename); updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100); o_log(INFORMATION, "Conversion process: Complete"); // Do OCR - on this page // - OCR libs just wants the raw data and not the image header ocrImage( uuid, docid, current_page, request_resolution, pix, lang ); #ifdef CAN_PHASH // Calulate the pHash, so we can compare images later if( current_page == 1 ) { updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0); unsigned long long hash = getImagePhash_px( pix ); savePhash( docid, hash ); } #endif /* CAN_PHASH */ pixDestroy( &pix ); // cleaup && What should we do next // o_log(DEBUGM, "mostly done."); if(current_page >= total_requested_pages) updateScanProgress(uuid, SCAN_FINISHED, docid); else updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page); o_log(DEBUGM, "Page scan done."); return o_strdup("OK"); }
extern char *internalGetScannerList(char *lang) { char *answer = NULL; SANE_Status status; const SANE_Device **SANE_device_list; int scanOK = SANE_FALSE; char *deviceList; status = sane_get_devices (&SANE_device_list, SANE_TRUE); if(status == SANE_STATUS_GOOD) { if (SANE_device_list && SANE_device_list[0]) { scanOK = SANE_TRUE; o_log(DEBUGM, "device(s) found"); } else { o_log(INFORMATION, "No devices found"); } } else { o_log(WARNING, "Checking for devices failed"); } if(scanOK == SANE_TRUE) { int i = 0; char *replyTemplate; replyTemplate = o_strdup("<Device><vendor>%s</vendor><model>%s</model><type>%s</type><name>%s</name><host>%s</host></Device>"); deviceList = o_strdup(""); for (i=0 ; SANE_device_list[i] ; i++) { char *vendor, *model, *type, *name; char *scannerHost; vendor = o_strdup(SANE_device_list[i]->vendor); model = o_strdup(SANE_device_list[i]->model); type = o_strdup(SANE_device_list[i]->type); name = o_strdup(SANE_device_list[i]->name); propper(vendor); propper(model); propper(type); // Find location of the device if ( name && name == strstr(name, "net:") ) { struct sockaddr_in sa; char *ipandmore, *ip; char host[NI_MAXHOST]; char service[NI_MAXSERV]; int len; // Ignore the 'net:' part ipandmore = name + 4; // Find the length of the address part len = strstr(ipandmore, ":") - ipandmore; // Load 'ip' with the network addres ip = malloc(1+(size_t)len); (void) strncpy(ip,ipandmore,(size_t)len); ip[len] = '\0'; // Convert into an inet address memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr( ip ); // Lookup hostname from address o_log(DEBUGM, "Going to lookup: %s", ip); if ( getnameinfo((struct sockaddr *)&sa, sizeof sa, host, sizeof host, service, sizeof service, NI_NAMEREQD) == 0 ) { o_log(DEBUGM, "found host: %s", host); scannerHost = o_strdup(host); } else { o_log(DEBUGM, "Could not get hostname"); scannerHost = o_strdup(ip); } // Clean up free(ip); } else { scannerHost = o_strdup( getString("LOCAL_opendias_server", lang) ); } // Build Reply // o_concatf(&deviceList, replyTemplate, vendor, model, type, name, scannerHost); free(vendor); free(model); free(type); free(name); free(scannerHost); } free(replyTemplate); if(deviceList) { // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%%s><Devices>%s</Devices></ScannerList></Response>", deviceList); free(deviceList); } else { // No devices // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>"); } } else { // sane failed. // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>"); } return answer; }
extern char *internalGetScannerDetails(char *device, char *lang) { char *answer = NULL; SANE_Status status; char *deviceList = o_strdup("");; int hlp = 0, resolution = 300, minRes=50, maxRes=50, phashAvailable=0; char *resolution_s, *maxRes_s, *minRes_s; SANE_Handle *openDeviceHandle; o_log(DEBUGM, "sane_open of \"%s\"", device); status = sane_open (device, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { o_log(ERROR, "Could not open: '%s' with error: %s", device, sane_strstatus(status)); free(deviceList); return NULL; } // // Find resolution ranges // for (hlp = 0; hlp < 9999; hlp++) { const SANE_Option_Descriptor *sod; sod = sane_get_option_descriptor (openDeviceHandle, hlp); if (sod == NULL) break; // Just a placeholder if (sod->type == SANE_TYPE_GROUP || sod->name == NULL || hlp == 0) continue; if ( 0 == strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) ) { // Some kind of sliding range if (sod->constraint_type == SANE_CONSTRAINT_RANGE) { o_log(DEBUGM, "Resolution setting detected as 'range'"); // Fixed resolution if (sod->type == SANE_TYPE_FIXED) maxRes = (int)SANE_UNFIX (sod->constraint.range->max); else maxRes = sod->constraint.range->max; } // A fixed list of options else if (sod->constraint_type == SANE_CONSTRAINT_WORD_LIST) { int lastIndex = sod->constraint.word_list[0]; o_log(DEBUGM, "Resolution setting detected as 'word list': lastIndex = %d",lastIndex); // maxRes = sod->constraint.word_list[lastIndex]; // resolution list cannot be treated as low to high ordered list // remark: impl capability to select scan resolution in webInterface int n=0; maxRes = 0; for (n=1; n<=lastIndex; n++ ) { o_log(DEBUGM, "index results %d --> %d", n ,(int)sod->constraint.word_list[n]); if ( maxRes < sod->constraint.word_list[n] ) { maxRes=sod->constraint.word_list[n]; } } } break; // we've found our resolution - no need to search more } } o_log(DEBUGM, "Determined max resultion to be %d", maxRes); // Define a default if(resolution >= maxRes) resolution = maxRes; if(resolution <= minRes) resolution = minRes; o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // // What languages can we OCR for? // char *availableLangs = o_strdup(""); #ifdef CAN_OCR struct simpleLinkedList *languages = getOCRAvailableLanguages(); while (languages != NULL ) { if ( checkOCRLanguage( languages->data ) == 0 ) { o_concatf(&availableLangs, "<lang>%s</lang>", languages->data); } languages = sll_getNext(languages); } sll_destroy( languages ); #endif /* CAN_OCR */ // // Can we give the option of doing 'find simmilar'? // #ifdef CAN_PHASH phashAvailable = 1; #endif /* CAN_PHASH */ // Build Reply // resolution_s = itoa(resolution,10); maxRes_s = itoa(maxRes,10); minRes_s = itoa(minRes,10); o_concatf(&deviceList, "<Resolution><max>%s</max><min>%s</min><default>%s</default></Resolution><OCRLanguages>%s</OCRLanguages><phash>%d</phash>", maxRes_s, minRes_s, resolution_s, availableLangs, phashAvailable); free(maxRes_s); free(minRes_s); free(resolution_s); free(availableLangs); // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerDetails>%s</ScannerDetails></Response>", deviceList); free(deviceList); return answer; }
extern char *addNewScannedDoc (int getLines, int ppl, int resolution, int pageCount) { return addNewDoc(SCAN_FILETYPE, getLines, ppl, resolution, pageCount, o_strdup("") ); }
/** * Initialize the application configuration based on the config file content * Read the config file, get mandatory variables and devices */ int build_config_from_file(struct config_elements * config) { config_t cfg; config_setting_t * root, * database; const char * cur_prefix, * cur_log_mode, * cur_log_level, * cur_log_file = NULL, * one_log_mode, * db_type, * db_sqlite_path, * db_mariadb_host = NULL, * db_mariadb_user = NULL, * db_mariadb_password = NULL, * db_mariadb_dbname = NULL; int db_mariadb_port = 0; config_init(&cfg); if (!config_read_file(&cfg, config->config_file)) { fprintf(stderr, "Error parsing config file %s\nOn line %d error: %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); return 0; } if (config->instance->port == -1) { // Get Port number to listen to int port; config_lookup_int(&cfg, "port", &port); config->instance->port = port; } if (config->url_prefix == NULL) { // Get prefix url if (config_lookup_string(&cfg, "url_prefix", &cur_prefix)) { config->url_prefix = o_strdup(cur_prefix); if (config->url_prefix == NULL) { fprintf(stderr, "Error allocating config->url_prefix, exiting\n"); config_destroy(&cfg); return 0; } } } if (config->log_mode == Y_LOG_MODE_NONE) { // Get log mode if (config_lookup_string(&cfg, "log_mode", &cur_log_mode)) { one_log_mode = strtok((char *)cur_log_mode, ","); while (one_log_mode != NULL) { if (0 == strncmp("console", one_log_mode, strlen("console"))) { config->log_mode |= Y_LOG_MODE_CONSOLE; } else if (0 == strncmp("syslog", one_log_mode, strlen("syslog"))) { config->log_mode |= Y_LOG_MODE_SYSLOG; } else if (0 == strncmp("file", one_log_mode, strlen("file"))) { config->log_mode |= Y_LOG_MODE_FILE; // Get log file path if (config->log_file == NULL) { if (config_lookup_string(&cfg, "log_file", &cur_log_file)) { config->log_file = o_strdup(cur_log_file); if (config->log_file == NULL) { fprintf(stderr, "Error allocating config->log_file, exiting\n"); config_destroy(&cfg); return 0; } } } } one_log_mode = strtok(NULL, ","); } } } if (config->log_level == Y_LOG_LEVEL_NONE) { // Get log level if (config_lookup_string(&cfg, "log_level", &cur_log_level)) { if (0 == strncmp("NONE", cur_log_level, strlen("NONE"))) { config->log_level = Y_LOG_LEVEL_NONE; } else if (0 == strncmp("ERROR", cur_log_level, strlen("ERROR"))) { config->log_level = Y_LOG_LEVEL_ERROR; } else if (0 == strncmp("WARNING", cur_log_level, strlen("WARNING"))) { config->log_level = Y_LOG_LEVEL_WARNING; } else if (0 == strncmp("INFO", cur_log_level, strlen("INFO"))) { config->log_level = Y_LOG_LEVEL_INFO; } else if (0 == strncmp("DEBUG", cur_log_level, strlen("DEBUG"))) { config->log_level = Y_LOG_LEVEL_DEBUG; } } } if (!y_init_logs(GARETH_LOG_NAME, config->log_mode, config->log_level, config->log_file, "Starting Gareth alert and messenger service")) { fprintf(stderr, "Error initializing logs\n"); exit_server(&config, GARETH_ERROR); } root = config_root_setting(&cfg); database = config_setting_get_member(root, "database"); if (database != NULL) { if (config_setting_lookup_string(database, "type", &db_type) == CONFIG_TRUE) { if (0 == strncmp(db_type, "sqlite3", strlen("sqlite3"))) { if (config_setting_lookup_string(database, "path", &db_sqlite_path) == CONFIG_TRUE) { config->conn = h_connect_sqlite(db_sqlite_path); if (config->conn == NULL) { config_destroy(&cfg); fprintf(stderr, "Error opening sqlite database %s\n", db_sqlite_path); return 0; } } else { config_destroy(&cfg); fprintf(stderr, "Error, no sqlite database specified\n"); return 0; } } else if (0 == strncmp(db_type, "mariadb", strlen("mariadb"))) { config_setting_lookup_string(database, "host", &db_mariadb_host); config_setting_lookup_string(database, "user", &db_mariadb_user); config_setting_lookup_string(database, "password", &db_mariadb_password); config_setting_lookup_string(database, "dbname", &db_mariadb_dbname); config_setting_lookup_int(database, "port", &db_mariadb_port); config->conn = h_connect_mariadb(db_mariadb_host, db_mariadb_user, db_mariadb_password, db_mariadb_dbname, db_mariadb_port, NULL); if (config->conn == NULL) { fprintf(stderr, "Error opening mariadb database %s\n", db_mariadb_dbname); config_destroy(&cfg); return 0; } } else { config_destroy(&cfg); fprintf(stderr, "Error, database type unknown\n"); return 0; } } else { config_destroy(&cfg); fprintf(stderr, "Error, no database type found\n"); return 0; } } else { config_destroy(&cfg); fprintf(stderr, "Error, no database setting found\n"); return 0; } config_destroy(&cfg); return 1; }
extern int addTagToDoc (char *docid, char *tagid) { char *sql = o_strdup("INSERT INTO doc_tags (docid, tagid) VALUES (?, ?) "); return addRemoveTagOnDocument(sql, docid, tagid); }
/** * Initialize the application configuration based on the command line parameters */ int build_config_from_args(int argc, char ** argv, struct config_elements * config) { int next_option; const char * short_options = "c::p::b::u::d::a::s::m::l::f::r::h::"; char * tmp = NULL, * to_free = NULL, * one_log_mode = NULL; static const struct option long_options[]= { {"config-file", optional_argument,NULL, 'c'}, {"port", optional_argument,NULL, 'p'}, {"url-prefix", optional_argument,NULL, 'u'}, {"log-mode", optional_argument,NULL, 'm'}, {"log-level", optional_argument,NULL, 'l'}, {"log-file", optional_argument,NULL, 'f'}, {"help", optional_argument,NULL, 'h'}, {NULL, 0, NULL, 0} }; if (config != NULL) { do { next_option = getopt_long(argc, argv, short_options, long_options, NULL); switch (next_option) { case 'c': if (optarg != NULL) { config->config_file = o_strdup(optarg); if (config->config_file == NULL) { fprintf(stderr, "Error allocating config->config_file, exiting\n"); exit_server(&config, GARETH_STOP); } } else { fprintf(stderr, "Error!\nNo config file specified\n"); return 0; } break; case 'p': if (optarg != NULL) { config->instance->port = strtol(optarg, NULL, 10); if (config->instance->port <= 0 || config->instance->port > 65535) { fprintf(stderr, "Error!\nInvalid TCP Port number\n\tPlease specify an integer value between 1 and 65535"); return 0; } } else { fprintf(stderr, "Error!\nNo TCP Port number specified\n"); return 0; } break; case 'u': if (optarg != NULL) { config->url_prefix = o_strdup(optarg); if (config->url_prefix == NULL) { fprintf(stderr, "Error allocating config->url_prefix, exiting\n"); exit_server(&config, GARETH_STOP); } } else { fprintf(stderr, "Error!\nNo URL prefix specified\n"); return 0; } break; case 'm': if (optarg != NULL) { tmp = o_strdup(optarg); if (tmp == NULL) { fprintf(stderr, "Error allocating log_mode, exiting\n"); exit_server(&config, GARETH_STOP); } one_log_mode = strtok(tmp, ","); while (one_log_mode != NULL) { if (0 == strncmp("console", one_log_mode, strlen("console"))) { config->log_mode |= Y_LOG_MODE_CONSOLE; } else if (0 == strncmp("syslog", one_log_mode, strlen("syslog"))) { config->log_mode |= Y_LOG_MODE_SYSLOG; } else if (0 == strncmp("file", one_log_mode, strlen("file"))) { config->log_mode |= Y_LOG_MODE_FILE; } one_log_mode = strtok(NULL, ","); } free(to_free); } else { fprintf(stderr, "Error!\nNo mode specified\n"); return 0; } break; case 'l': if (optarg != NULL) { if (0 == strncmp("NONE", optarg, strlen("NONE"))) { config->log_level = Y_LOG_LEVEL_NONE; } else if (0 == strncmp("ERROR", optarg, strlen("ERROR"))) { config->log_level = Y_LOG_LEVEL_ERROR; } else if (0 == strncmp("WARNING", optarg, strlen("WARNING"))) { config->log_level = Y_LOG_LEVEL_WARNING; } else if (0 == strncmp("INFO", optarg, strlen("INFO"))) { config->log_level = Y_LOG_LEVEL_INFO; } else if (0 == strncmp("DEBUG", optarg, strlen("DEBUG"))) { config->log_level = Y_LOG_LEVEL_DEBUG; } } else { fprintf(stderr, "Error!\nNo log level specified\n"); return 0; } break; case 'f': if (optarg != NULL) { config->log_file = o_strdup(optarg); if (config->log_file == NULL) { fprintf(stderr, "Error allocating config->log_file, exiting\n"); exit_server(&config, GARETH_STOP); } } else { fprintf(stderr, "Error!\nNo log file specified\n"); return 0; } break; case 'h': exit_server(&config, GARETH_STOP); break; } } while (next_option != -1); // If none exists, exit failure if (config->config_file == NULL) { fprintf(stderr, "No configuration file found, please specify a configuration file path\n"); return 0; } return 1; } else { return 0; } }
extern int removeTagFromDoc (char *docid, char *tagid) { char *sql = o_strdup("DELETE FROM doc_tags WHERE docid = ? AND tagid = ? "); return addRemoveTagOnDocument(sql, docid, tagid); }