From 0a157185ad157e09bf74609c7eac3a9cf730a22d Mon Sep 17 00:00:00 2001 From: nidhijainpnp <12njain06@gmail.com> Date: Mon, 7 Sep 2020 01:02:12 +0530 Subject: [PATCH] using select() to read ippfind output inCUPS array --- utils/driverless.c | 318 +++++++++++++++------------------------------ 1 file changed, 108 insertions(+), 210 deletions(-) diff --git a/utils/driverless.c b/utils/driverless.c index d1edb57fb..99e41b310 100644 --- a/utils/driverless.c +++ b/utils/driverless.c @@ -58,30 +58,33 @@ convert_to_port(char *a) return (port); } + /* * 'copy_output()' - copy ippfind output data . */ static int /* O - 0 on success, -1 on error */ -copy_output(int read_fd, /* I - Print file descriptor */ - int write_fd) /* I - Device file descriptor */ +copy_output(int read_ipp_fd, /* I - IPP file descriptor */ + int read_ipps_fd, /* I - IPPS file descriptor */ + cups_array_t *service_uri_list_ipps, /* I - IPPS CUPS Array */ + cups_array_t *service_uri_list_ipp) /* I - IPP CUPS Array */ { int nfds; /* Maximum file descriptor value + 1 */ fd_set input; /* Input set for reading */ - ssize_t print_bytes, /* Print bytes read */ - bytes; /* Bytes written */ - char print_buffer[MAX_OUTPUT_LEN], /* Print data buffer */ - *print_ptr; /* Pointer into print data buffer */ struct timeval timeout; /* Timeout for read... */ - - + cups_file_t *fp; + int bytes; + char *ptr, + buffer[MAX_OUTPUT_LEN], /* Copy buffer */ + *ippfind_output; + /* * Figure out the maximum file descriptor value to use with select()... */ - nfds = (read_fd > write_fd ? read_fd : write_fd) + 1; + nfds = (read_ipp_fd > read_ipps_fd ? read_ipp_fd : read_ipps_fd) + 1; /* - * Now loop until we are out of data from read_fd... + * Now loop until we are out of data from read_ipp_fd and read_ipps_fd... */ for (;;) @@ -91,71 +94,114 @@ copy_output(int read_fd, /* I - Print file descriptor */ */ FD_ZERO(&input); - FD_SET(read_fd, &input); + FD_SET(read_ipp_fd, &input); + FD_SET(read_ipps_fd, &input); timeout.tv_sec = 2; timeout.tv_usec = 0; if (select(nfds, &input, NULL, NULL, &timeout) < 0) return (-1); - if (!FD_ISSET(read_fd, &input)) - { + if (!FD_ISSET(read_ipp_fd, &input) && !FD_ISSET(read_ipps_fd, &input)) + { return (0); - } + } - if ((print_bytes = read(read_fd, print_buffer, - sizeof(print_buffer))) < 0) + + if(FD_ISSET(read_ipps_fd, &input)) { - /* - * Read error - bail if we don't see EAGAIN or EINTR... - */ + dup2(read_ipps_fd, 0); + + fp = cupsFileStdin(); - if (errno != EAGAIN && errno != EINTR) + if ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0) { - perror("ERROR: Unable to read print data"); - return (-1); + ippfind_output = (char *)malloc(MAX_OUTPUT_LEN*(sizeof(char))); + ptr = buffer; + while (ptr && !isalnum(*ptr & 255)) ptr ++; + + if ((!strncasecmp(ptr, "ipps", 4) && ptr[4] == '\t')) + { + ptr += 4; + *ptr = '\0'; + ptr ++; + } else + continue; + snprintf(ippfind_output, MAX_OUTPUT_LEN, "%s", ptr); + cupsArrayAdd(service_uri_list_ipps,ippfind_output); + } + else if (bytes < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + if (errno != EAGAIN && errno != EINTR) + { + perror("ERROR: Unable to read print data"); + return (-1); + } + } + else + { + /* + * End of file, return... + */ + return (0); } - - print_bytes = 0; - } - else if (print_bytes == 0) - { - /* - * End of file, return... - */ - return (0); } - - for (print_ptr = print_buffer; print_bytes > 0;) + + if(FD_ISSET(read_ipp_fd, &input)) { - if ((bytes = write(write_fd, print_ptr, print_bytes)) < 0) + dup2(read_ipp_fd, 0); + fp = cupsFileStdin(); + if ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0) { - /* - * Write error - bail if we don't see an error we can retry... - */ - - if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN && - errno != EINTR && errno != ENOTTY) - { - perror("ERROR: Unable to write print data"); - return (-1); - } + ippfind_output = (char *)malloc(MAX_OUTPUT_LEN*(sizeof(char))); + ptr = buffer; + + + while (ptr && !isalnum(*ptr & 255)) ptr ++; + + if ((!strncasecmp(ptr, "ipp", 3) && ptr[3] == '\t')) + { + ptr += 3; + *ptr = '\0'; + ptr ++; + } else + continue; + snprintf(ippfind_output, MAX_OUTPUT_LEN, "%s", ptr); + cupsArrayAdd(service_uri_list_ipp,ippfind_output); + } + else if (bytes < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + if (errno != EAGAIN && errno != EINTR) + { + perror("ERROR: Unable to read print data"); + return (-1); + } } else { - print_bytes -= bytes; - print_ptr += bytes; + /* + * End of file, return... + */ + return (0); } + } + } } - void listPrintersInArray(int reg_type_no, int mode, int isFax, char* ippfind_output ) { int driverless_support = 0, /*process id for ippfind */ port, is_local; - + + char buffer[8192], /* Copy buffer */ *ptr, /* Pointer into string */ *scheme = NULL, @@ -473,12 +519,7 @@ list_printers (int mode, int reg_type_no, int isFax) cupsArrayNew((cups_array_func_t)compare_service_uri, NULL); service_uri_list_ipp = cupsArrayNew((cups_array_func_t)compare_service_uri, NULL); - char *ippfind_output; - - cups_file_t *fp; /* Post-processing input file */ - int bytes; - char *ptr; - char buffer[8192]; /* Copy buffer */ + /* * Use CUPS' ippfind utility to discover all printers designed for @@ -634,156 +675,21 @@ list_printers (int mode, int reg_type_no, int isFax) ippfind_ipp_pid); } - + close(post_proc_pipe_ipp[1]); + close(post_proc_pipe_ipps[1]); /* - Copy data to pipe + * Reading the ippfind output in CUPS Array */ - int read_data_pipe_ipp[2], - read_data_pipe_ipps[2]; - int read_data_pid_ipp = 0, - read_data_pid_ipps = 0; - int read_status_ipp , - read_status_ipps; - - if (pipe(read_data_pipe_ipp)) { - perror("ERROR: Unable to create pipe to copy data for ipp "); - exit_status = 1; - goto error; - } - if (reg_type_no <= 1) { - if ((read_data_pid_ipp = fork()) == 0) - { - /* - * Child comes here... - */ - close(post_proc_pipe_ipp[1]); - close(read_data_pipe_ipp[0]); - read_status_ipp = copy_output(post_proc_pipe_ipp[0],read_data_pipe_ipp[1]); - if(read_status_ipp < 0) - exit(1); - exit(0); - } else if (read_data_pid_ipp < 0) { - /* - * Unable to fork! - */ - perror("ERROR: Unable to read ipp data"); - exit_status = 1; - goto error; - } - if (debug) - fprintf(stderr, "DEBUG: Started reading ipp data (PID %d)\n", - read_data_pid_ipp); - } + int copy_output_exit_status = 0; + copy_output_exit_status = copy_output(post_proc_pipe_ipp[0],post_proc_pipe_ipps[0],service_uri_list_ipps,service_uri_list_ipp); - - if (pipe(read_data_pipe_ipps)) { - perror("ERROR: Unable to create pipe to copy data for ipps "); - exit_status = 1; + if(copy_output_exit_status < 0) + { + exit_status = copy_output_exit_status; goto error; } - if (reg_type_no >= 1) { - if ((read_data_pid_ipps = fork()) == 0) - { - /* - * Child comes here... - */ - close(post_proc_pipe_ipps[1]); - close(read_data_pipe_ipps[0]); - read_status_ipps = copy_output(post_proc_pipe_ipps[0],read_data_pipe_ipps[1]); - if(read_status_ipps < 0) - exit(1); - exit(0); - } else if (read_data_pid_ipps < 0) { - /* - * Unable to fork! - */ - perror("ERROR: Unable to read ipps data"); - exit_status = 1; - goto error; - } - if (debug) - fprintf(stderr, "DEBUG: Started reading ipps data (PID %d)\n", - read_data_pid_ipps); - } - - /* - Reading the ippfind output in CUPS Array - */ - if(reg_type_no >=1) - { - dup2(read_data_pipe_ipps[0], 0); - close(read_data_pipe_ipps[0]); - close(read_data_pipe_ipps[1]); - - fp = cupsFileStdin(); - - while ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0) - { - ippfind_output = (char *)malloc(MAX_OUTPUT_LEN*(sizeof(char))); - if (ippfind_output == NULL) - { - exit_status = 1; - goto error; - } - - ptr = buffer; - - while (ptr && !isalnum(*ptr & 255)) ptr ++; - - if ((!strncasecmp(ptr, "ipps", 4) && ptr[4] == '\t')) - { - ptr += 4; - *ptr = '\0'; - ptr ++; - } else - continue; - snprintf(ippfind_output, MAX_OUTPUT_LEN, "%s", ptr); - cupsArrayAdd(service_uri_list_ipps,ippfind_output); - } - /* - * Copy the rest of the file - */ - while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) - fwrite(buffer, 1, bytes, stdout); - } - if(reg_type_no <=1) - { - dup2(read_data_pipe_ipp[0], 0); - close(read_data_pipe_ipp[0]); - close(read_data_pipe_ipp[1]); - fp = cupsFileStdin(); - while ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0) - { - ippfind_output = (char *)malloc(MAX_OUTPUT_LEN*(sizeof(char))); - if (ippfind_output == NULL) - { - exit_status = 1; - goto error; - } - - ptr = buffer; - - while (ptr && !isalnum(*ptr & 255)) ptr ++; - if ((!strncasecmp(ptr, "ipp", 3) && ptr[3] == '\t')) - { - ptr += 3; - *ptr = '\0'; - ptr ++; - } else - continue; - snprintf(ippfind_output, MAX_OUTPUT_LEN, "%s", ptr); - cupsArrayAdd(service_uri_list_ipp,ippfind_output); - } - /* - * Copy the rest of the file - */ - while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) - fwrite(buffer, 1, bytes, stdout); - } - - for(int j = 0 ; j< cupsArrayCount(service_uri_list_ipp);j++) { if(cupsArrayFind(service_uri_list_ipps,(char*)cupsArrayIndex(service_uri_list_ipp,j)) @@ -799,7 +705,7 @@ list_printers (int mode, int reg_type_no, int isFax) * Wait for the child processes to exit... */ - wait_children = 4; + wait_children = 2; while (wait_children > 0) { /* @@ -810,8 +716,7 @@ list_printers (int mode, int reg_type_no, int isFax) if (job_canceled) { kill(ippfind_ipps_pid, SIGTERM); kill(ippfind_ipp_pid, SIGTERM); - kill(read_data_pid_ipp, SIGTERM); - kill(read_data_pid_ipps, SIGTERM); + job_canceled = 0; } } @@ -833,8 +738,6 @@ list_printers (int mode, int reg_type_no, int isFax) fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n", wait_pid, wait_pid == ippfind_ipps_pid ? "ippfind _ipps._tcp" : - wait_pid == read_data_pid_ipp ? "read ipp data" : - wait_pid == read_data_pid_ipps ? "read ipps data" : (wait_pid == ippfind_ipp_pid ? "ippfind _ipp._tcp" : "Unknown process"), exit_status); @@ -848,8 +751,6 @@ list_printers (int mode, int reg_type_no, int isFax) "DEBUG: PID %d (%s) was terminated normally with signal %d!\n", wait_pid, wait_pid == ippfind_ipps_pid ? "ippfind _ipps._tcp" : - wait_pid == read_data_pid_ipp ? "read ipp data" : - wait_pid == read_data_pid_ipps ? "read ipps data" : (wait_pid == ippfind_ipp_pid ? "ippfind _ipp._tcp" : "Unknown process"), exit_status); @@ -860,8 +761,6 @@ list_printers (int mode, int reg_type_no, int isFax) fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n", wait_pid, wait_pid == ippfind_ipps_pid ? "ippfind _ipps._tcp" : - wait_pid == read_data_pid_ipp ? "read ipp data" : - wait_pid == read_data_pid_ipps ? "read ipps data" : (wait_pid == ippfind_ipp_pid ? "ippfind _ipp._tcp" : "Unknown process"), exit_status); @@ -871,8 +770,6 @@ list_printers (int mode, int reg_type_no, int isFax) fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n", wait_pid, wait_pid == ippfind_ipps_pid ? "ippfind _ipps._tcp" : - wait_pid == read_data_pid_ipp ? "read ipp data" : - wait_pid == read_data_pid_ipps ? "read ipps data" : (wait_pid == ippfind_ipp_pid ? "ippfind _ipp._tcp" : "Unknown process")); } @@ -886,8 +783,9 @@ list_printers (int mode, int reg_type_no, int isFax) */ error: - - return (exit_status); + cupsArrayDelete(service_uri_list_ipps); + cupsArrayDelete(service_uri_list_ipp); + return (exit_status); } int -- 2.47.2