Skip to content

Commit

Permalink
Add mainloop support, implementing basic scan API
Browse files Browse the repository at this point in the history
Signed-off-by: Akarshan Kapoor <[email protected]>
  • Loading branch information
Kappuccino111 committed Nov 3, 2024
1 parent a34e612 commit 980c312
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 4 deletions.
5 changes: 1 addition & 4 deletions pappl/mainloop-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ extern int _papplMainloopCancelJob(const char *base_name, cups_len_t num_options
extern int _papplMainloopDeletePrinter(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopDeleteScanner(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopGetSetDefaultPrinter(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopGetSetDefaultScanner(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopModifyPrinter(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopPausePrinter(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopResumePrinter(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
Expand All @@ -48,18 +47,16 @@ extern int _papplMainloopShowDrivers(const char *base_name, cups_len_t num_drive
extern int _papplMainloopShowJobs(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopShowOptions(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopShowPrinters(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopShowScanners(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopShowStatus(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopShutdownServer(const char *base_name, cups_len_t num_options, cups_option_t *options) _PAPPL_PRIVATE;
extern int _papplMainloopSubmitJob(const char *base_name, cups_len_t num_options, cups_option_t *options, cups_len_t num_files, char **files) _PAPPL_PRIVATE;

extern void _papplMainloopAddOptions(ipp_t *request, cups_len_t num_options, cups_option_t *options, ipp_t *supported) _PAPPL_PRIVATE;
extern void _papplMainloopAddPrinterURI(ipp_t *request, const char *printer_name, char *resource,size_t rsize) _PAPPL_PRIVATE;
extern void _papplMainloopAddScannerURI(ipp_t *request, const char *scanner_name, char *resource, size_t rsize) _PAPPL_PRIVATE; // Request type ipp ?
extern int _papplMainloopAddScannerURI(http_t *request, const char *scanner_name, char *resource, size_t rsize) _PAPPL_PRIVATE; // Request type ipp ?
extern http_t *_papplMainloopConnect(const char *base_name, bool auto_start) _PAPPL_PRIVATE;
extern http_t *_papplMainloopConnectURI(const char *base_name, const char *printer_uri, char *resource, size_t rsize) _PAPPL_PRIVATE;
extern char *_papplMainloopGetDefaultPrinter(http_t *http, char *buffer, size_t bufsize) _PAPPL_PRIVATE;
extern char *_papplMainloopGetDefaultScanner(http_t *http, char *buffer, size_t bufsize) _PAPPL_PRIVATE;
extern char *_papplMainloopGetServerPath(const char *base_name, uid_t uid, char *buffer, size_t bufsize) _PAPPL_PRIVATE;
extern int _papplMainloopGetServerPort(const char *base_name) _PAPPL_PRIVATE;

Expand Down
101 changes: 101 additions & 0 deletions pappl/mainloop-subcommands.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,107 @@ _papplMainloopDeletePrinter(
return (0);
}

//
// '_papplMainloopDeleteScanner()' - Delete a scanner registration.
//

int // O - Exit status
_papplMainloopDeleteScanner(
const char *base_name, // I - Base name
cups_len_t num_options, // I - Number of options
cups_option_t *options) // I - Options
{
http_t *http = NULL; // Connection to server
const char *device_uri, // Device URI
*scanner_name, // Name of scanner
*scanner_uri, // Scanner URI
*escl_path; // eSCL resource path
char resource[1024]; // Resource path for connection
bool status = false; // Status of scanner deletion
http_status_t response; // HTTP response status

// Get required values...
device_uri = cupsGetOption("device-uri", (int)num_options, options);
scanner_name = cupsGetOption("scanner-name", (int)num_options, options);
escl_path = cupsGetOption("escl", (int)num_options, options);

// Check if we're deleting a remote scanner
scanner_uri = cupsGetOption("scanner-uri", (int)num_options, options);
if (scanner_uri)
{
// Connect to the remote scanner...
http = _papplMainloopConnectURI(base_name, scanner_uri, resource, sizeof(resource));
if (!http)
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Unable to connect to remote scanner at '%s'"),
base_name, scanner_uri);
return (1);
}
}
else
{
// Validate required parameters for local scanner
if (!scanner_name)
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Missing '-d SCANNER'."), base_name);
return (1);
}

if (!device_uri)
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Missing '-v DEVICE-URI'."), base_name);
return (1);
}

// Connect to local scanner
http = httpConnect2(device_uri, 0, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
if (!http)
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Unable to connect to scanner at '%s'"),
base_name, device_uri);
return (1);
}
}

// Set up eSCL path
if (!escl_path)
escl_path = "/eSCL/"; // Default eSCL path if not specified

// Construct the deletion path
char delete_path[1024];
snprintf(delete_path, sizeof(delete_path), "%sregistration/%s",
escl_path, scanner_name);

// Send DELETE request to remove scanner registration
httpClearFields(http);

if (httpDelete(http, delete_path) != HTTP_STATUS_OK)
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Unable to send deletion request: %s"),
base_name, cupsGetErrorString());
httpClose(http);
return (1);
}

// Check the response
response = httpUpdate(http);
if (response == HTTP_STATUS_OK || response == HTTP_STATUS_NO_CONTENT)
{
status = true;
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Successfully deleted scanner '%s'"),
base_name, scanner_name);
}
else
{
_papplLocPrintf(stderr, _PAPPL_LOC("%s: Scanner deletion failed with status %d"),
base_name, response);
}

// Clean up
httpClose(http);

return (status ? 0 : 1);
}

//
// '_papplMainloopGetSetDefaultPrinter()' - Get/set the default printer.
Expand Down
57 changes: 57 additions & 0 deletions pappl/mainloop-support.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,63 @@ _papplMainloopAddPrinterURI(
}


// '_papplMainloopAddScannerURI()' - Add the scanner-uri attribute and return a
// resource path.
//

int
_papplMainloopAddScannerURI(
http_t *request, // I - HTTP request
const char *scanner_name, // I - Scanner name
char *resource, // I - Resource path buffer
size_t rsize) // I - Size of buffer
{
char uri[1024]; // scanner-uri value
char *resptr; // Pointer into resource path
int ret;

// Construct the initial resource path for the scanner
ret = snprintf(resource, rsize, "/escl/scan/%s", scanner_name);
if (ret < 0 || (size_t)ret >= rsize) {
fprintf(stderr, "Error: Resource path buffer too small.\n");
return -1;
}

// Sanitize the resource path by replacing invalid characters with '_'
for (resptr = resource + strlen("/escl/scan/"); *resptr; resptr++) {
if ((*resptr & 255) <= ' ' || strchr("\177/\\\'\"?#", *resptr)) {
*resptr = '_';
}
}

// Eliminate duplicate and trailing underscores
resptr = resource + strlen("/escl/scan/");
while (*resptr) {
if (resptr[0] == '_' && resptr[1] == '_') {
memmove(resptr, resptr + 1, strlen(resptr));
// Duplicate underscores removed, do not advance resptr
}
else if (resptr[0] == '_' && !resptr[1]) {
*resptr = '\0'; // Trailing underscore removed
break;
}
else {
resptr++;
}
}

// Assemble the full URI using HTTP
ret = httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "http", NULL, "localhost", 0, resource);

if (ret < 0) {
fprintf(stderr, "Error: Failed to assemble URI.\n");
return -1;
}

httpSetField(request, HTTP_FIELD_CONTENT_TYPE, uri);
return 0;
}

//
// '_papplMainloopConnect()' - Connect to the local server.
//
Expand Down

0 comments on commit 980c312

Please sign in to comment.