bool status( LSHandle *handle, LSMessage *msg, void *ctx) { if(rec_status()) { LSMessageRespond( msg, "{\"returnValue\": true, \"Status\": true}", NULL); return true; } else LSMessageRespond( msg, "{\"rerurnValue\": true, \"Status\": false}", NULL); return true; }
bool getFilecacheType_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); if (access_denied(message)) return true; char filename[MAXLINLEN]; // Extract the id argument from the message json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *type = json_find_first_label(object, "type"); if (!type || (type->child->type != JSON_STRING) || (strspn(type->child->text, ALLOWED_CHARS) != strlen(type->child->text))) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing type\"}", &lserror)) goto error; return true; } sprintf(filename, "/etc/palm/filecache_types/%s", type->child->text); return read_file(message, filename, true); error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
// // Handler for the getStats service. // bool getStats_handler(LSHandle* lshandle, LSMessage *reply, void *ctx) { bool retVal; LSError lserror; LSErrorInit(&lserror); LSMessage* message = (LSMessage*)ctx; retVal = LSMessageRespond(message, LSMessageGetPayload(reply), &lserror); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } return retVal; }
// // Encrypt text // bool encrypt_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); // Local buffer to store the update command char command[MAXLINLEN]; char *document; // Extract the userdata argument from the message json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *userdata = json_find_first_label(object, "userdata"); if (!userdata || (userdata->child->type != JSON_OBJECT)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing userdata\"}", &lserror)) goto error; return true; } if (json_tree_to_string(userdata->child, &document) != JSON_OK) { if (!LSMessageRespond(message, "{\"errorText\": \"Unable to parse userdata\", \"returnValue\": false, \"errorCode\": -1 }", &lserror)) goto error; return true; } // Store the command, so it can be used in the error report if necessary sprintf(command, "echo '%s' | openssl rsautl -encrypt -certin -inkey /media/cryptofs/apps/usr/palm/applications/com.apptuckerbox.register/certs/com.apptuckerbox.crt | openssl enc -e -a 2>&1", document); return simple_command(message, command); error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
static bool access_denied(LSMessage *message) { LSError lserror; LSErrorInit(&lserror); const char *appId = LSMessageGetApplicationID(message); if (!appId || strncmp(appId, "org.webosinternals.impostah", 27) || ((strlen(appId) > 27) && (*(appId+27) != ' '))) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorText\": \"Unauthorised access\"}", &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } return true; } return false; }
// // Return the current API version of the service. // Called directly from webOS, and returns directly to webOS. // bool version_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); if (access_denied(message)) return true; if (!LSMessageRespond(message, "{\"returnValue\": true, \"version\": \"" VERSION "\", \"apiVersion\": \"" API_VERSION "\"}", &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
// // A dummy method, useful for unimplemented functions or as a status function. // Called directly from webOS, and returns directly to webOS. // bool dummy_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); if (access_denied(message)) return true; if (!LSMessageRespond(message, "{\"returnValue\": true}", &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
// // Handler for the impersonate service. // bool impersonate_handler(LSHandle* lshandle, LSMessage *reply, void *ctx) { bool retVal; LSError lserror; LSErrorInit(&lserror); LSMessage* message = (LSMessage*)ctx; retVal = LSMessageRespond(message, LSMessageGetPayload(reply), &lserror); if (!LSMessageIsSubscription(message)) { LSMessageUnref(message); } if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } return retVal; }
static bool access_denied(LSMessage *message) { LSError lserror; LSErrorInit(&lserror); const char *appId = LSMessageGetApplicationID(message); if (!appId || strncmp(appId, "com.apptuckerbox.register", 25) || ((strlen(appId) > 25) && (*(appId+25) != ' '))) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorText\": \"Unauthorised access\"}", &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } return true; } return false; }
// // Send a standard format command failure message back to webOS. // The command will be escaped. The output argument should be a JSON array and is not escaped. // The additional text will not be escaped. // The return value is from the LSMessageRespond call, not related to the command execution. // static bool report_command_failure(LSMessage *message, char *command, char *stdErrText, char *additional) { LSError lserror; LSErrorInit(&lserror); char buffer[MAXBUFLEN]; char esc_buffer[MAXBUFLEN]; // Include the command that was executed, in escaped form. snprintf(buffer, MAXBUFLEN, "{\"errorText\": \"Unable to run command: %s\"", json_escape_str(command, esc_buffer)); // Include any stderr fields from the command. if (stdErrText) { strcat(buffer, ", \"stdErr\": "); strcat(buffer, stdErrText); } // Report that an error occurred. strcat(buffer, ", \"returnValue\": false, \"errorCode\": -1"); // Add any additional JSON fields. if (additional) { strcat(buffer, ", "); strcat(buffer, additional); } // Terminate the JSON reply message ... strcat(buffer, "}"); // fprintf(stderr, "Message is %s\n", buffer); // and send it. if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
// // Run a simple shell command, and return the output to webOS. // static bool simple_command(LSMessage *message, char *command) { LSError lserror; LSErrorInit(&lserror); char run_command_buffer[MAXBUFLEN]; // Initialise the output buffer strcpy(run_command_buffer, "{\"stdOut\": ["); // Run the command if (run_command(command, true, run_command_buffer)) { // Finalise the message ... strcat(run_command_buffer, "], \"returnValue\": true}"); // fprintf(stderr, "Message is %s\n", run_command_buffer); // and send it to webOS. if (!LSMessageRespond(message, run_command_buffer, &lserror)) goto error; } else { // Finalise the command output ... strcat(run_command_buffer, "]"); // and use it in a failure report message. if (!report_command_failure(message, command, run_command_buffer+11, NULL)) goto end; } return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
bool importUsWords(LSHandle *handle, LSMessage *msg, void *ctx) { puts("importUsWords"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool phraseGetInfoList(LSHandle *handle, LSMessage *msg, void *ctx) { puts("phraseGetInfoList"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool loadPhrase(LSHandle *handle, LSMessage *msg, void *ctx) { puts("loadPhrase"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool getListCandList(LSHandle *handle, LSMessage *msg, void *ctx) { puts("getListCandList"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool put_file_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); char buffer[MAXBUFLEN]; json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *id; // Extract the url argument from the message id = json_find_first_label(object, "filename"); if (!id || (id->child->type != JSON_STRING) || (strlen(id->child->text) >= MAXLINLEN) || (strlen(id->child->text) < 8) || strncmp(id->child->text, "file://", 7)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, " "\"errorText\": \"Invalid or missing filename parameter\"}", &lserror)) goto error; return true; } char filename[MAXLINLEN]; strcpy(filename, id->child->text+7); // Extract the object argument from the message id = json_find_first_label(object, "object"); if (!id || (id->child->type != JSON_OBJECT)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, " "\"errorText\": \"Invalid or missing object parameter\"}", &lserror)) goto error; return true; } char *contents = NULL; if (json_tree_to_string(id->child, &contents) != JSON_OK) { sprintf(buffer, "{\"errorText\": \"Unable to parse object\", \"returnValue\": false, \"errorCode\": -1 }"); if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; } FILE *fp = fopen(filename, "w"); if (!fp) { sprintf(buffer, "{\"errorText\": \"Unable to open %s\", \"returnValue\": false, \"errorCode\": -1 }", filename); if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; } if (fputs(contents, fp) == EOF) { (void)fclose(fp); (void)unlink(filename); sprintf(buffer, "{\"errorText\": \"Unable to write to %s\", \"returnValue\": false, \"errorCode\": -1 }", filename); if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; } if (fclose(fp)) { sprintf(buffer, "{\"errorText\": \"Unable to close %s\", \"returnValue\": false, \"errorCode\": -1 }", filename); if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; } if (!LSMessageRespond(message, "{\"returnValue\": true}", &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
static bool read_file(LSMessage *message, char *filename, bool subscribed) { LSError lserror; LSErrorInit(&lserror); FILE * file = fopen(filename, "r"); if (!file) { sprintf(file_buffer, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Cannot open %s\"}", filename); if (!LSMessageRespond(message, file_buffer, &lserror)) goto error; return true; } char chunk[CHUNKSIZE]; int chunksize = CHUNKSIZE; syslog(LOG_DEBUG, "Reading file %s\n", filename); fseek(file, 0, SEEK_END); int filesize = ftell(file); fseek(file, 0, SEEK_SET); if (subscribed) { if (sprintf(file_buffer, "{\"returnValue\": true, \"filesize\": %d, \"chunksize\": %d, \"stage\": \"start\"}", filesize, chunksize)) { if (!LSMessageRespond(message, file_buffer, &lserror)) goto error; } } else if (filesize < chunksize) { chunksize = filesize; } int size; int datasize = 0; while ((size = fread(chunk, 1, chunksize, file)) > 0) { datasize += size; chunk[size] = '\0'; sprintf(file_buffer, "{\"returnValue\": true, \"size\": %d, \"contents\": \"", size); strcat(file_buffer, json_escape_str(chunk, file_esc_buffer)); strcat(file_buffer, "\""); if (subscribed) { strcat(file_buffer, ", \"stage\": \"middle\""); } strcat(file_buffer, "}"); if (!LSMessageRespond(message, file_buffer, &lserror)) goto error; } if (!fclose(file)) { if (subscribed) { sprintf(file_buffer, "{\"returnValue\": true, \"datasize\": %d, \"stage\": \"end\"}", datasize); if (!LSMessageRespond(message, file_buffer, &lserror)) goto error; } } else { sprintf(file_buffer, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Cannot close file\"}"); if (!LSMessageRespond(message, file_buffer, &lserror)) goto error; } return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
bool setShuangpin(LSHandle *handle, LSMessage *msg, void *ctx) { puts("setShuangpin"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool findLian(LSHandle *handle, LSMessage *msg, void *ctx) { puts("findLian"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool cellInstall(LSHandle *handle, LSMessage *msg, void *ctx) { puts("cellInstall"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
// // Dump the contents of an sqlite3 database table // static bool dump_sqlite(LSMessage *message, char *database, char *table) { LSError lserror; LSErrorInit(&lserror); char buffer[MAXBUFLEN]; char esc_buffer[MAXBUFLEN]; char line[MAXLINLEN]; // Local buffer to store the command char command[MAXLINLEN]; sprintf(command, "sqlite3 %s .dump 2>&1", database); // Is this the first line of output? bool first = true; // Was there an error in accessing any of the files? bool error = false; // Length of buffer before the last command int lastlen = 0; // Start execution of the command to list the config files. FILE *fp = popen(command, "r"); // If the command cannot be started if (!fp) { // then report the error to webOS. if (!report_command_failure(message, command, NULL, NULL)) goto end; // The error report has been sent, so return to webOS. return true; } if (!LSMessageRespond(message, "{\"stage\": \"start\", \"returnValue\": true}", &lserror)) goto error; // Initialise the output message. strcpy(buffer, "{"); lastlen = strlen(buffer); // Loop through the list of files in the scripts directory. while (fgets( line, sizeof line, fp)) { // Chomp the newline char *nl = strchr(line,'\n'); if (nl) *nl = 0; if ((strlen(line) <= 13+strlen(table)+9) || strncmp(line, "INSERT INTO \"", 13) || strncmp(line+13, table, strlen(table)) || strncmp(line+13+strlen(table), "\" VALUES(", 9) || strncmp(line+strlen(line)-2, ");", 2)) { continue; } *(line+strlen(line)-2) = 0; // Push out a partial chunk if (strlen(buffer) >= CHUNKSIZE) { // Terminate the JSON array if (!first) { strcat(buffer, "], "); } strcat(buffer, "\"stage\": \"middle\", "); // Check the error status, and return the current error status if (error) { strcat(buffer, "\"returnValue\": false}"); } else { strcat(buffer, "\"returnValue\": true}"); } // fprintf(stderr, "Message is %s\n", buffer); // Return the results to webOS. if (!LSMessageRespond(message, buffer, &lserror)) goto error; // This is now the first line of output first = true; // Initialise the output message. strcpy(buffer, "{"); lastlen = strlen(buffer); } // Start or continue the JSON array if (first) { strcat(buffer, "\"results\": ["); lastlen = strlen(buffer); first = false; } else if (strlen(buffer) > lastlen) { strcat(buffer, ", "); lastlen = strlen(buffer); } // Store the command output strcat(buffer, "\""); strcat(buffer, json_escape_str(line+13+strlen(table)+9, esc_buffer)); strcat(buffer, "\""); } // Terminate the JSON array if (!first) { strcat(buffer, "], "); } strcat(buffer, "\"stage\": \"end\", "); // Check the close status of the process, and return the combined error status if (pclose(fp) || error) { strcat(buffer, "\"returnValue\": false}"); } else { strcat(buffer, "\"returnValue\": true}"); } // fprintf(stderr, "Message is %s\n", buffer); // Return the results to webOS. if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
bool getSysLibVer(LSHandle *handle, LSMessage *msg, void *ctx) { puts("getSysLibVer"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
// // Impersonate a call to the requested service and return the output to webOS. // bool impersonate_method(LSHandle* lshandle, LSMessage *message, void *ctx) { bool retVal; LSError lserror; LSErrorInit(&lserror); LSMessageRef(message); if (access_denied(message)) return true; // Extract the method argument from the message json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *id = json_find_first_label(object, "id"); if (!id || (id->child->type != JSON_STRING)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing id\"}", &lserror)) goto error; return true; } // Extract the service argument from the message object = json_parse_document(LSMessageGetPayload(message)); json_t *service = json_find_first_label(object, "service"); if (!service || (service->child->type != JSON_STRING)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing service\"}", &lserror)) goto error; return true; } // Extract the method argument from the message object = json_parse_document(LSMessageGetPayload(message)); json_t *method = json_find_first_label(object, "method"); if (!method || (method->child->type != JSON_STRING)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing method\"}", &lserror)) goto error; return true; } // Extract the params argument from the message object = json_parse_document(LSMessageGetPayload(message)); json_t *params = json_find_first_label(object, "params"); if (!params || (params->child->type != JSON_OBJECT)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing params\"}", &lserror)) goto error; return true; } char uri[MAXLINLEN]; sprintf(uri, "palm://%s/%s", service->child->text, method->child->text); char *paramstring = NULL; json_tree_to_string (params->child, ¶mstring); if (!LSCallFromApplication(priv_serviceHandle, uri, paramstring, id->child->text, impersonate_handler, message, NULL, &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
bool getMatchInfo(LSHandle *handle, LSMessage *msg, void *ctx) { puts("getMatchInfo"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
// // Get the listing of a directory, and return it's contents. // bool get_dir_listing_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); char buffer[MAXBUFLEN]; char esc_buffer[MAXBUFLEN]; struct dirent *ep; // Local buffer to hold each line of output from ls char line[MAXLINLEN]; // Is this the first line of output? bool first = true; // Was there an error in accessing any of the files? bool error = false; json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *id = json_find_first_label(object, "directory"); if (!id || (id->child->type != JSON_STRING) || (strspn(id->child->text, ALLOWED_CHARS"/") != strlen(id->child->text))) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Invalid or missing directory\"}", &lserror)) goto error; } // Start execution of the command to list the directory contents DIR *dp = opendir(id->child->text); // If the command cannot be started if (!dp) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, \"errorText\": \"Unable to open directory\"}", &lserror)) goto error; // The error report has been sent, so return to webOS. return true; } // Initialise the output message. strcpy(buffer, "{"); // Loop through the list of directory entries. while (ep = readdir(dp)) { // Start or continue the JSON array if (first) { strcat(buffer, "\"contents\": ["); first = false; } else { strcat(buffer, ", "); } strcat(buffer, "{\"name\":\""); strcat(buffer, json_escape_str(ep->d_name, esc_buffer)); strcat(buffer, "\", "); strcat(buffer, "\"type\":\""); if (ep->d_type == DT_DIR) { strcat(buffer, "directory"); } else if (ep->d_type == DT_REG) { strcat(buffer, "file"); } else if (ep->d_type == DT_LNK) { strcat(buffer, "symlink"); } else { strcat(buffer, "other"); } strcat(buffer, "\"}"); } // Terminate the JSON array if (!first) { strcat(buffer, "], "); } // Check the close status of the process, and return the combined error status if (closedir(dp) || error) { strcat(buffer, "\"returnValue\": false}"); } else { strcat(buffer, "\"returnValue\": true}"); } // Return the results to webOS. if (!LSMessageRespond(message, buffer, &lserror)) goto error; return true; error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }
bool hsEnd(LSHandle *handle, LSMessage *msg, void *ctx) { puts("hsEnd"); LSMessageRespond(msg, "{\"returnValue\": true}", NULL); return true; }
bool get_file_method(LSHandle* lshandle, LSMessage *message, void *ctx) { LSError lserror; LSErrorInit(&lserror); char run_command_buffer[MAXBUFLEN]; char command[MAXLINLEN]; json_t *object = json_parse_document(LSMessageGetPayload(message)); json_t *id; // Extract the filename argument from the message id = json_find_first_label(object, "filename"); if (!id || (id->child->type != JSON_STRING) || (strlen(id->child->text) >= MAXNAMLEN) || (strspn(id->child->text, ALLOWED_CHARS) != strlen(id->child->text))) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, " "\"errorText\": \"Invalid or missing filename parameter\", " "\"stage\": \"failed\"}", &lserror)) goto error; return true; } char filename[MAXNAMLEN]; sprintf(filename, "/media/internal/.temp/%s", id->child->text); // Extract the url argument from the message id = json_find_first_label(object, "url"); if (!id || (id->child->type != JSON_STRING) || (strlen(id->child->text) >= MAXLINLEN)) { if (!LSMessageRespond(message, "{\"returnValue\": false, \"errorCode\": -1, " "\"errorText\": \"Invalid or missing url parameter\", " "\"stage\": \"failed\"}", &lserror)) goto error; return true; } char url[MAXLINLEN]; strcpy(url, id->child->text); if (!strncmp(url, "file://", 7)) { strcpy(filename, url+7); } else { /* Download the package */ snprintf(command, MAXLINLEN, "/usr/bin/curl --create-dirs --insecure --location --fail --show-error --output %s %s 2>&1", filename, url); strcpy(run_command_buffer, "{\"stdOut\": ["); if (run_command(command, true, run_command_buffer)) { strcat(run_command_buffer, "], \"returnValue\": true, \"stage\": \"download\"}"); if (!LSMessageRespond(message, run_command_buffer, &lserror)) goto error; } else { strcat(run_command_buffer, "]"); if (!report_command_failure(message, command, run_command_buffer+11, "\"stage\": \"failed\"")) goto end; return true; } } return read_file(message, filename, true); error: LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); end: return false; }