int merge_N_SIMD (void *ail, uint *ids, uint nids, uint *noccs, uint **occs){ lpair* lengths = (lpair*)malloc(sizeof(lpair)*nids); for(unsigned int i=0;i<nids;i++){ lengths[i].pos = ids[i]; lenlist(ail, ids[i], &(lengths[i].len)); } qsort(lengths, nids, sizeof(lpair), &lpair_compare); uint* arr1; uint resLen; uint *res; merge_2_uncompressFstSIMD(ail, lengths[0].pos, lengths[1].pos, &resLen, &arr1); res=arr1; for(unsigned int i=2;(i<nids)&&(resLen);i++){ uint len2; uint* arr2; extractList_il(ail, lengths[i].pos, &arr2, &len2); res = intersect_aux_simd(arr1,resLen,arr2,len2,&resLen); free(arr1); free(arr2); arr1=res; //printf("\n next merge = %lu occs (len1=%u, len2=%u)",resLen, resLen, len); } free(lengths); //if (!resLen) {free(res); res=NULL;} *occs = res; *noccs = resLen; return 0; }
int merge_N (void *ail, uint *ids, uint nids, uint *noccs, uint **occs){ // fprintf(stderr,"\n call to mergeN") // {uint i; // fprintf(stderr,"\n Call to svsN:: "); // for (i=0;i<nids;i++) fprintf(stderr,"[%d]",ids[i]); // } lpair* lengths = (lpair*)malloc(sizeof(lpair)*nids); for(unsigned int i=0;i<nids;i++){ lengths[i].pos = ids[i]; lenlist(ail, ids[i], &(lengths[i].len)); } qsort(lengths, nids, sizeof(lpair), &lpair_compare); uint* auxArr; uint auxLen; merge_2_uncompressFst(ail, lengths[0].pos, lengths[1].pos, &auxLen, &auxArr); //printf("\n initial merge = %lu occs (len1=%u, len2=%u)",auxLen,lengths[0].len, lengths[1].len); for(unsigned int i=2;(i<nids)&&(auxLen);i++){ uint len; uint* arr; extractList_il(ail, lengths[i].pos, &arr, &len); auxArr = intersect_aux(auxArr,auxLen,arr,len,&auxLen); //printf("\n next merge = %lu occs (len1=%u, len2=%u)",auxLen, auxLen, len); free(arr); } free(lengths); //if (!auxLen) {free(auxArr); auxArr=NULL;} *occs = auxArr; *noccs = auxLen; return 0; }
void plotResults(uint id1, uint id2, double tiempo, uint iter, char *matlab, char* outfile) { FILE *f = fopen(outfile,"a"); uint a,b,x; double y; //fprintf(stderr,"\n call to plot id1=%d, id2=%d, tiempo = %f, iter = %d, matlab = %s, outfile = %s",id1,id2,tiempo,iter,matlab,outfile); lenlist(Index,id1,&a); lenlist(Index,id2,&b); //fprintf(stderr,"\n a= %d, b=%d",a,b); //fprintf(stderr,"\nid1= %u a= %d // id2=%u b=%d",id1,a,id2,b); x= ((a+(b-1))/b); //fprintf(stderr,"\n x=%d",x); fprintf(stderr,"#"); if ((iter%100)==0) fprintf(stderr,"<%d>",iter); y=tiempo; fprintf(f,"\n%sX(%d)=%d;",matlab,iter,x); fprintf(f,"\n%sY(%d)=%f;",matlab,iter,y); acumTimes[x] += y; ncount[x]++; fclose(f); }
/*VARARGS1*/ int exec(int type, ...) { va_list args; int i; int procuid; int procgid; int ret; int fr_flg; char *cp; char *infile; char *outfile; char *errfile; char *sep; char **listp; char **file_list; char *printerName; char *printerNameToShow; static char nameBuf[100]; char *clean_title; PSTATUS *printer; RSTATUS *request; FSTATUS *form; EXEC *ep; PWSTATUS *pwheel; time_t now; struct passwd *pwp; #ifdef LP_USE_PAPI_ATTR struct stat tmpBuf; char tmpName[BUFSIZ]; char *path = NULL; #endif char *av[ARG_MAX]; char **envp = NULL; int ac = 0; char *mail_zonename = NULL; char *slabel = NULL; syslog(LOG_DEBUG, "exec(%s)", _exec_name(type)); memset(av, 0, sizeof (*av)); va_start (args, type); switch (type) { case EX_INTERF: printer = va_arg(args, PSTATUS *); request = printer->request; ep = printer->exec; break; case EX_FAULT_MESSAGE: printer = va_arg(args, PSTATUS *); request = va_arg(args, RSTATUS *); if (! ( printer->status & (PS_FORM_FAULT | PS_SHOW_FAULT))) { return(0); } ep = printer->fault_exec; printerName = (printer->printer && printer->printer->name ? printer->printer->name : "??"); snprintf(nameBuf, sizeof (nameBuf), "%s (on %s)\n", printerName, Local_System); printerNameToShow = nameBuf; (void) time(&now); (void) strftime(time_buf, sizeof (time_buf), NULL, localtime(&now)); break; case EX_SLOWF: request = va_arg(args, RSTATUS *); ep = request->exec; break; case EX_NOTIFY: request = va_arg(args, RSTATUS *); if (request->request->actions & ACT_NOTIFY) { errno = EINVAL; return (-1); } ep = request->exec; break; case EX_ALERT: printer = va_arg(args, PSTATUS *); if (!(printer->printer->fault_alert.shcmd)) { errno = EINVAL; return(-1); } ep = printer->alert->exec; break; case EX_PALERT: pwheel = va_arg(args, PWSTATUS *); ep = pwheel->alert->exec; break; case EX_FORM_MESSAGE: (void) time(&now); (void) strftime(time_buf, sizeof (time_buf), NULL, localtime(&now)); /*FALLTHRU*/ case EX_FALERT: form = va_arg(args, FSTATUS *); ep = form->alert->exec; break; default: errno = EINVAL; return(-1); } va_end (args); if (!ep || (ep->pid > 0)) { errno = EBUSY; return(-1); } ep->flags = 0; key = ep->key = getkey(); switch ((ep->pid = Fork1(ep))) { case -1: relock (); return(-1); case 0: /* * We want to be able to tell our parent how we died. */ lp_alloc_fail_handler = child_mallocfail; break; default: switch(type) { case EX_INTERF: request->request->outcome |= RS_PRINTING; break; case EX_NOTIFY: request->request->outcome |= RS_NOTIFYING; break; case EX_SLOWF: request->request->outcome |= RS_FILTERING; request->request->outcome &= ~RS_REFILTER; break; } return(0); } for (i = 0; i < NSIG; i++) (void)signal (i, SIG_DFL); (void)signal (SIGALRM, SIG_IGN); (void)signal (SIGTERM, sigtrap); closelog(); for (i = 0; i < OpenMax; i++) if (i != ChildMd->writefd) Close (i); openlog("lpsched", LOG_PID|LOG_NDELAY|LOG_NOWAIT, LOG_LPR); setpgrp(); /* Set a default path */ addenv (&envp, "PATH", "/usr/lib/lp/bin:/usr/bin:/bin:/usr/sbin:/sbin"); /* copy locale related variables */ addenv (&envp, "TZ", getenv("TZ")); addenv (&envp, "LANG", getenv("LANG")); addenv (&envp, "LC_ALL", getenv("LC_ALL")); addenv (&envp, "LC_COLLATE", getenv("LC_COLLATE")); addenv (&envp, "LC_CTYPE", getenv("LC_CTYPE")); addenv (&envp, "LC_MESSAGES", getenv("LC_MESSAGES")); addenv (&envp, "LC_MONETARY", getenv("LC_MONETARY")); addenv (&envp, "LC_NUMERIC", getenv("LC_NUMERIC")); addenv (&envp, "LC_TIME", getenv("LC_TIME")); sprintf ((cp = BIGGEST_NUMBER_S), "%ld", key); addenv (&envp, "SPOOLER_KEY", cp); #if defined(DEBUG) addenv (&envp, "LPDEBUG", (debug? "1" : "0")); #endif /* * Open the standard input, standard output, and standard error. */ switch (type) { case EX_SLOWF: case EX_INTERF: /* * stdin: /dev/null * stdout: /dev/null (EX_SLOWF), printer port (EX_INTERF) * stderr: req# */ infile = 0; outfile = 0; errfile = makereqerr(request); break; case EX_NOTIFY: /* * stdin: req# * stdout: /dev/null * stderr: /dev/null */ infile = makereqerr(request); outfile = 0; errfile = 0; break; case EX_ALERT: case EX_FALERT: case EX_PALERT: case EX_FAULT_MESSAGE: case EX_FORM_MESSAGE: /* * stdin: /dev/null * stdout: /dev/null * stderr: /dev/null */ infile = 0; outfile = 0; errfile = 0; break; } if (infile) { if (Open(infile, O_RDONLY) == -1) Done (EXEC_EXIT_NOPEN, errno); } else { if (Open("/dev/null", O_RDONLY) == -1) Done (EXEC_EXIT_NOPEN, errno); } if (outfile) { if (Open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0600) == -1) Done (EXEC_EXIT_NOPEN, errno); } else { /* * If EX_INTERF, this is still needed to cause the * standard error channel to be #2. */ if (Open("/dev/null", O_WRONLY) == -1) Done (EXEC_EXIT_NOPEN, errno); } if (errfile) { if (Open(errfile, O_CREAT|O_TRUNC|O_WRONLY, 0600) == -1) Done (EXEC_EXIT_NOPEN, errno); } else { if (Open("/dev/null", O_WRONLY) == -1) Done (EXEC_EXIT_NOPEN, errno); } switch (type) { case EX_INTERF: /* * Opening a ``port'' can be dangerous to our health: * * - Hangups can occur if the line is dropped. * - The printer may send an interrupt. * - A FIFO may be closed, generating SIGPIPE. * * We catch these so we can complain nicely. */ trap_fault_signals (); (void)Close (1); if (strchr (request->request->user, '@')) { procuid = Lp_Uid; procgid = Lp_Gid; } else { procuid = request->secure->uid; procgid = request->secure->gid; } if (printer->printer->dial_info) { ret = open_dialup(request->printer_type, printer->printer); if (ret == 0) do_undial = 1; } else { ret = open_direct(request->printer_type, printer->printer); do_undial = 0; /* this is a URI */ if (is_printer_uri(printer->printer->device) == 0) addenv(&envp, "DEVICE_URI", printer->printer->device); } addenv(&envp, "DEVICE_URI", printer->printer->device); if (ret != 0) Done (ret, errno); if (!(request->request->outcome & RS_FILTERED)) file_list = request->request->file_list; else { register int count = 0; register char * num = BIGGEST_REQID_S; register char * prefix; prefix = makestr( Lp_Temp, "/F", getreqno(request->secure->req_id), "-", (char *)0 ); file_list = (char **)Malloc( (lenlist(request->request->file_list) + 1) * sizeof(char *) ); for ( listp = request->request->file_list; *listp; listp++ ) { sprintf (num, "%d", count + 1); file_list[count] = makestr( prefix, num, (char *)0 ); count++; } file_list[count] = 0; } #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file exists, if it does * pass the file's pathname to the printer interface script * in an environment variable. This file is created when * print jobs are submitted via the PAPI interface. */ snprintf(tmpName, sizeof (tmpName), "%s-%s", getreqno(request->secure->req_id), LP_PAPIATTRNAME); path = makepath(Lp_Temp, tmpName, (char *)0); if ((path != NULL) && (stat(path, &tmpBuf) == 0)) { /* * IPP job attribute file exists for this job so * set the environment variable */ addenv(&envp, "ATTRPATH", path); } Free(path); /* * now set environment variable for the printer's PostScript * Printer Description (PPD) file, this is used by the filter * when forming the print data for this printer. */ if ((request->printer != NULL) && (request->printer->printer != NULL) && (request->printer->printer->name != NULL)) { snprintf(tmpName, sizeof (tmpName), "%s.ppd", request->printer->printer->name); path = makepath(ETCDIR, "ppd", tmpName, (char *)0); if ((path != NULL) && (stat(path, &tmpBuf) == 0)) { addenv(&envp, "PPD", path); } Free(path); } #endif if (request->printer_type) addenv(&envp, "TERM", request->printer_type); if (!(printer->printer->daisy)) { register char * chset = 0; register char * csp; if ( request->form && request->form->form->chset && request->form->form->mandatory && !STREQU(NAME_ANY, request->form->form->chset) ) chset = request->form->form->chset; else if ( request->request->charset && !STREQU(NAME_ANY, request->request->charset) ) chset = request->request->charset; if (chset) { csp = search_cslist( chset, printer->printer->char_sets ); /* * The "strtok()" below wrecks the string * for future use, but this is a child * process where it won't be needed again. */ addenv (&envp, "CHARSET", (csp? strtok(csp, "=") : chset) ); } } if (request->fast) addenv(&envp, "FILTER", request->fast); /* * Add the sensitivity label to the environment for * banner page and header/footer processing */ if (is_system_labeled() && request->secure->slabel != NULL) addenv(&envp, "SLABEL", request->secure->slabel); /* * Add the system name to the user name (ala system!user) * unless it is already there. RFS users may have trouble * here, sorry! */ cp = strchr(request->secure->user, '@'); allTraysWithForm(printer, request->form); /* * Fix for 4137389 * Remove double quotes from title string. */ fr_flg = 1; clean_title = strdup(NB(request->request->title)); if (clean_title == NULL) { /* * strdup failed. We're probably hosed * but try setting clean_title * to original title and continuing. */ clean_title = NB(request->request->title); fr_flg = 0; } else if (strcmp(clean_title, "") != 0) { char *ct_p; for (ct_p = clean_title; *ct_p != NULL; ct_p++) { if (*ct_p == '"') *ct_p = ' '; } } av[ac++] = arg_string(TRUSTED, "%s/%s", Lp_A_Interfaces, printer->printer->name); av[ac++] = arg_string(TRUSTED, "%s", request->secure->req_id); av[ac++] = arg_string(UNTRUSTED, "%s", request->request->user); av[ac++] = arg_string(TRUSTED, "%s", clean_title); av[ac++] = arg_string(TRUSTED, "%d", request->copies); if (fr_flg) free (clean_title); sep = ""; /* * Do the administrator defined key=value pair options */ argbuf[0] = '\0'; if (printer->printer->options) { char **tmp = printer->printer->options; while(*tmp != NULL) { STRLCAT(argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT(argbuf, *tmp++, sizeof (argbuf)); } } /* * Do the administrator defined ``stty'' stuff before * the user's -o options, to allow the user to override. */ if (printer->printer->stty) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "stty='", sizeof (argbuf)); STRLCAT (argbuf, printer->printer->stty, sizeof (argbuf)); STRLCAT (argbuf, "'", sizeof (argbuf)); } /* * Do all of the user's options except the cpi/lpi/etc. * stuff, which is done separately. */ if (request->request->options) { listp = dashos(request->request->options); while (*listp) { if ( !STRNEQU(*listp, "cpi=", 4) && !STRNEQU(*listp, "lpi=", 4) && !STRNEQU(*listp, "width=", 6) && !STRNEQU(*listp, "length=", 7) ) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, *listp, sizeof (argbuf)); } listp++; } } /* * The "pickfilter()" routine (from "validate()") * stored the cpi/lpi/etc. stuff that should be * used for this request. It chose form over user, * and user over printer. */ if (request->cpi) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "cpi=", sizeof (argbuf)); STRLCAT (argbuf, request->cpi, sizeof (argbuf)); } if (request->lpi) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "lpi=", sizeof (argbuf)); STRLCAT (argbuf, request->lpi, sizeof (argbuf)); } if (request->pwid) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "width=", sizeof (argbuf)); STRLCAT (argbuf, request->pwid, sizeof (argbuf)); } if (request->plen) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "length=", sizeof (argbuf)); STRLCAT (argbuf, request->plen, sizeof (argbuf)); } /* * Do the ``raw'' bit last, to ensure it gets * done. If the user doesn't want this, then he or * she can do the correct thing using -o stty= * and leaving out the -r option. */ if (request->request->actions & ACT_RAW) { STRLCAT (argbuf, sep, sizeof (argbuf)); sep = " "; STRLCAT (argbuf, "stty=-opost", sizeof (argbuf)); } /* the "options" */ av[ac++] = arg_string(UNTRUSTED, "%s", argbuf); for (listp = file_list; *listp; listp++) av[ac++] = arg_string(TRUSTED, "%s", *listp); (void)chfiles (file_list, procuid, procgid); break; case EX_SLOWF: if (request->slow) addenv(&envp, "FILTER", request->slow); if (strchr (request->request->user, '@')) { procuid = Lp_Uid; procgid = Lp_Gid; } else { procuid = request->secure->uid; procgid = request->secure->gid; } cp = _alloc_files( lenlist(request->request->file_list), getreqno(request->secure->req_id), procuid, procgid); av[ac++] = arg_string(TRUSTED, "%s", Lp_Slow_Filter); av[ac++] = arg_string(TRUSTED, "%s/%s", Lp_Temp, cp); for (listp = request->request->file_list; *listp; listp++) av[ac++] = arg_string(TRUSTED, "%s", *listp); (void)chfiles (request->request->file_list, procuid, procgid); #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file exists, if it does * pass the file's pathname to the slow-filters in an * environment variable. Note: this file is created when * print jobs are submitted via the PAPI interface. */ snprintf(tmpName, sizeof (tmpName), "%s-%s", getreqno(request->secure->req_id), LP_PAPIATTRNAME); path = makepath(Lp_Temp, tmpName, (char *)0); if ((path != NULL) && (stat(path, &tmpBuf) == 0)) { /* * IPP job attribute file exists for this job so * set the environment variable */ addenv(&envp, "ATTRPATH", path); } Free(path); /* * now set environment variable for the printer's PostScript * Printer Description (PPD) file, this is used by the filter * when forming the print data for this printer. */ if ((request->printer != NULL) && (request->printer->printer != NULL) && (request->printer->printer->name != NULL)) { snprintf(tmpName, sizeof (tmpName), "%s.ppd", request->printer->printer->name); path = makepath(ETCDIR, "ppd", tmpName, (char *)0); if ((path != NULL) && (stat(path, &tmpBuf) == 0)) { addenv(&envp, "PPD", path); } Free(path); } #endif break; case EX_ALERT: procuid = Lp_Uid; procgid = Lp_Gid; (void)Chown (printer->alert->msgfile, procuid, procgid); av[ac++] = arg_string(TRUSTED, "%s/%s/%s", Lp_A_Printers, printer->printer->name, ALERTSHFILE); av[ac++] = arg_string(TRUSTED, "%s", printer->alert->msgfile); break; case EX_PALERT: procuid = Lp_Uid; procgid = Lp_Gid; (void)Chown (pwheel->alert->msgfile, procuid, procgid); av[ac++] = arg_string(TRUSTED, "%s/%s/%s", Lp_A_PrintWheels, pwheel->pwheel->name, ALERTSHFILE); av[ac++] = arg_string(TRUSTED, "%s", printer->alert->msgfile); break; case EX_FALERT: procuid = Lp_Uid; procgid = Lp_Gid; (void)Chown (form->alert->msgfile, procuid, procgid); av[ac++] = arg_string(TRUSTED, "%s/%s/%s", Lp_A_Forms, form->form->name, ALERTSHFILE); av[ac++] = arg_string(TRUSTED, "%s", printer->alert->msgfile); break; case EX_FORM_MESSAGE: procuid = Lp_Uid; procgid = Lp_Gid; av[ac++] = arg_string(TRUSTED, "%s/form", Lp_A_Faults); av[ac++] = arg_string(TRUSTED, "%s", form->form->name); av[ac++] = arg_string(TRUSTED, "%s", time_buf); av[ac++] = arg_string(TRUSTED, "%s/%s/%s", Lp_A_Forms, form->form->name, FORMMESSAGEFILE); break; case EX_FAULT_MESSAGE: procuid = Lp_Uid; procgid = Lp_Gid; av[ac++] = arg_string(TRUSTED, "%s/printer", Lp_A_Faults); av[ac++] = arg_string(TRUSTED, "%s", printerNameToShow); av[ac++] = arg_string(TRUSTED, "%s", time_buf); av[ac++] = arg_string(TRUSTED, "%s/%s/%s", Lp_A_Printers, printerName, FAULTMESSAGEFILE); break; case EX_NOTIFY: if (request->request->alert) { if (strchr(request->request->user, '@')) { procuid = Lp_Uid; procgid = Lp_Gid; } else { procuid = request->secure->uid; procgid = request->secure->gid; } av[ac++] = arg_string(TRUSTED, "%s", request->request->alert); } else { char *user = strdup(request->request->user); clean_string(user); slabel = request->secure->slabel; if (request->request->actions & ACT_WRITE) { av[ac++] = arg_string(TRUSTED, "%s", BINWRITE); snprintf(argbuf, sizeof (argbuf), "%s %s || %s %s", BINWRITE, user, BINMAIL, user ); av[ac++] = arg_string(TRUSTED, "/bin/sh"); av[ac++] = arg_string(TRUSTED, "-c"); av[ac++] = arg_string(TRUSTED, "%s", argbuf); } else if ((getzoneid() == GLOBAL_ZONEID) && is_system_labeled() && (slabel != NULL)) { /* * If in the global zone and the system is * labeled, mail is handled via a local * labeled zone that is the same label as * the request. */ if ((mail_zonename = get_labeled_zonename(slabel)) == (char *)-1) { /* * Cannot find labeled zone, just * return 0. */ return(0); } } if (mail_zonename == NULL) { procuid = Lp_Uid; procgid = Lp_Gid; av[ac++] = arg_string(TRUSTED, "%s", BINMAIL); av[ac++] = arg_string(UNTRUSTED, "%s", user); } else { procuid = getuid(); procgid = getgid(); av[ac++] = arg_string(TRUSTED, "%s", "/usr/sbin/zlogin"); av[ac++] = arg_string(TRUSTED, "%s", mail_zonename); av[ac++] = arg_string(TRUSTED, "%s", BINMAIL); av[ac++] = arg_string(UNTRUSTED, "%s", user); Free(mail_zonename); } free(user); } break; } av[ac++] = NULL; Fork2 (); /* only the child returns */ /* * Correctly set up the supplemental group list * for proper file access (before execl the interface program) */ pwp = getpwuid(procuid); if (pwp == NULL) { note("getpwuid(%d) call failed\n", procuid); } else if (initgroups(pwp->pw_name, procgid) < 0) { note("initgroups() call failed %d\n", errno); } setgid (procgid); setuid (procuid); /* * The shell doesn't allow the "trap" builtin to set a trap * for a signal ignored when the shell is started. Thus, don't * turn off signals in the last child! */ #ifdef DEBUG for (i = 0; av[i] != NULL; i++) note("exec(%s): av[%d] = %s", _exec_name(type), i, av[i]); for (i = 0; envp[i] != NULL; i++) note("exec(%s): envp[%d] = %s", _exec_name(type), i, envp[i]); #endif execvpe(av[0], av, envp); Done (EXEC_EXIT_NEXEC, errno); /*NOTREACHED*/ return (0); }
int pickfilter(RSTATUS *prs, CANDIDATE *pc, FSTATUS *pfs) { register char ** pp; register char ** pl; register PSTATUS * pps = pc->pps; char * pipes[2] = { 0 , 0 }; char * cp; char * output_type; char ** modes = 0; char ** parms = 0; char ** valid_printer_types; char ** p_cpi = 0; char ** p_lpi = 0; char ** p_pwid = 0; char ** p_plen = 0; FILTERTYPE ret = fl_none; int got_cpi = 0; int got_lpi = 0; int got_plen = 0; int got_pwid = 0; int must_have_filter= 0; unsigned long chk; /* fix for bugid 1097387 */ output_type = (char *) NULL; /* * The bulk of the code below is building a parameter list "parms" * to send to "insfilter()". */ if (prs->request->modes) { cp = Strdup(prs->request->modes); transform_WS_to_SEP(cp); modes = getlist(cp, "", LP_SEP); Free (cp); } pp = parms = (char **)Malloc( 2 * (NPARM_SPEC + lenlist(modes) + 1) * sizeof(char *) ); /* * Add to the parameter list the appropriate cpi/lpi/etc. * characteristics (aka ``stuff'') that will be used for * this job. The printer defaults are questionable. * Take this opportunity to also save the ``stuff'' in * the request structure. */ unload_str (&(prs->cpi)); unload_str (&(prs->lpi)); unload_str (&(prs->plen)); unload_str (&(prs->pwid)); /* * If a form is involved, pick up its page size and print * spacing requirements. */ if (pfs) { if (pfs->cpi) { *pp++ = PARM_CPI; *pp++ = prs->cpi = pfs->cpi; got_cpi = 1; } if (pfs->lpi) { *pp++ = PARM_LPI; *pp++ = prs->lpi = pfs->lpi; got_lpi = 1; } if (pfs->plen) { *pp++ = PARM_LENGTH; *pp++ = prs->plen = pfs->plen; got_plen = 1; } if (pfs->pwid) { *pp++ = PARM_WIDTH; *pp++ = prs->pwid = pfs->pwid; got_pwid = 1; } /* * If no form is involved, pick up whatever page size and print * spacing requirements were given by the user. */ } else { if (o_cpi) { *pp++ = PARM_CPI; *pp++ = prs->cpi = o_cpi; got_cpi = 1; } if (o_lpi) { *pp++ = PARM_LPI; *pp++ = prs->lpi = o_lpi; got_lpi = 1; } if (o_length) { *pp++ = PARM_LENGTH; *pp++ = prs->plen = o_length; got_plen = 1; } if (o_width) { *pp++ = PARM_WIDTH; *pp++ = prs->pwid = o_width; got_pwid = 1; } } /* * Pick up whatever page size and print spacing requirements * haven't been specified yet from the printer defaults. * * Note: The following cpi/lpi/etc are guaranteed to work * for at least one type of the printer at hand, but not * necessarily all types. Once we pick a type that works * we'll verify that the cpi/lpi/etc stuff works, too. * The code that does that assumes that we do the following last, * after picking up the form and/or user stuff. If this changes, * then the later code will have to be changed, too. */ if (!got_cpi && pps->cpi) { *pp++ = PARM_CPI; *(p_cpi = pp++) = prs->cpi = pps->cpi; } if (!got_lpi && pps->lpi) { *pp++ = PARM_LPI; *(p_lpi = pp++) = prs->lpi = pps->lpi; } if (!got_plen && pps->plen) { *pp++ = PARM_LENGTH; *(p_plen = pp++) = prs->plen = pps->plen; } if (!got_pwid && pps->pwid) { *pp++ = PARM_WIDTH; *(p_pwid = pp++) = prs->pwid = pps->pwid; } /* * Pick up the number of pages, character set (the form's * or the user's), the form name, the number of copies, * and the modes. */ if (prs->request->pages) { *pp++ = PARM_PAGES; *pp++ = prs->request->pages; must_have_filter = 1; } if (prs->request->charset) { *pp++ = PARM_CHARSET; *pp++ = prs->request->charset; } else if (pfs && pfs->form->chset) { *pp++ = PARM_CHARSET; *pp++ = pfs->form->chset; } if (prs->request->form) { *pp++ = PARM_FORM; *pp++ = prs->request->form; } if (prs->request->copies > 1) { *pp++ = PARM_COPIES; sprintf ((*pp++ = BIGGEST_NUMBER_S), "%d", prs->request->copies); } if (modes) { for (pl = modes; *pl; pl++) { *pp++ = PARM_MODES; *pp++ = *pl; } must_have_filter = 1; } *pp = 0; /* null terminated list! */ /* * If the printer type(s) are not ``unknown'', then include * them as possible ``output'' type(s) to match * with the user's input type (directly, or through a filter). */ if (!STREQU(*(pps->printer->printer_types), NAME_UNKNOWN)) valid_printer_types = pc->printer_types; else { valid_printer_types = 0; must_have_filter = 0; } pc->fast = 0; pc->slow = 0; pc->output_type = 0; pc->flags = 0; ret = fl_none; /* * If we don't really need a filter and the types match, * then that's good enough. Some ``broadly defined'' * filters might match our needs, but if the printer * can do what we need, then why pull in a filter? * Besides, Section 3.40 in the requirements imply * that we don't use a filter if the printer can handle * the file. */ if (!must_have_filter ) { if ( valid_printer_types && searchlist_with_terminfo( prs->request->input_type, valid_printer_types ) ) { ret = fl_both; /* not really, but ok */ pc->printer_type = Strdup(prs->request->input_type); } else if ( pps->printer->input_types && searchlist_with_terminfo( prs->request->input_type, pps->printer->input_types ) ) { ret = fl_both; /* not really, but ok */ /* * (1) There is one printer type, might even * be ``unknown''; * (2) There are several printer types, but that * means only one input type, ``simple'', * which any of the printer types can handle. */ pc->printer_type = Strdup(*(pc->printer_types)); } } /* * Don't try using a filter if the user doesn't want * a filter to be used! He or she would rather see an * error message than (heaven forbid!) a filter being * used. */ if (ret == fl_none && !(prs->request->actions & ACT_RAW)) { /* * For each printer type, and each input type the printer * accepts, see if we have a filter that matches the * request to the printer. Each time we try, save the * output type we use in case of success; we just might * need that value later.... */ for ( pl = valid_printer_types; pl && *pl && ret == fl_none; pl++ ) ret = insfilter( pipes, prs->request->input_type, (output_type = *pl), *pl, pps->printer->name, parms, &(pc->flags) ); if (ret != fl_none) pc->printer_type = Strdup(*pl); for ( pl = pps->printer->input_types; pl && *pl && ret == fl_none; pl++ ) /* * Don't waste time with check we've already made. */ if ((must_have_filter == 1) || !valid_printer_types || !searchlist(*pl, valid_printer_types) ) /* * Either we have one (or less) printer * types and many input types, or we have * one input type, ``simple''; regardless, * using the first printer type is OK. */ ret = insfilter( pipes, prs->request->input_type, (output_type = *pl), *(pc->printer_types), pps->printer->name, parms, &(pc->flags) ); if (ret != fl_none) pc->printer_type = Strdup(*(pc->printer_types)); } /* * If we were successful, check that the printer type * we picked can handle the PRINTER'S cpi/lpi/etc. defaults. * (We know that ALL the printer's types can handle the stuff * the user gave or the stuff in the form.) * Each printer's default that doesn't pass muster gets dropped. * This may mean re-instantiating the filter(s) (if any). */ if (ret != fl_none && (p_cpi || p_lpi || p_pwid || p_plen)) { #define NZ(X) ((X)? *(X) : (char *)0) chk = chkprinter( pc->printer_type, NZ(p_cpi), NZ(p_lpi), NZ(p_plen), NZ(p_pwid), (char *)0 ); if (chk) { register char ** _pp; char * hole = ""; /* * Remove the offending printer defaults from the * request list of cpi/lpi/etc. stuff, and punch * (non-null!) holes in the parameter list. */ #define DROP(P,R) if (P) {P[-1] = P[0] = hole; R = 0;} else/*EMPTY*/ if (chk & PCK_CPI) DROP (p_cpi, prs->cpi); if (chk & PCK_LPI) DROP (p_lpi, prs->lpi); if (chk & PCK_WIDTH) DROP (p_pwid, prs->pwid); if (chk & PCK_LENGTH) DROP (p_plen, prs->plen); /* * If there are filters, we have to re-instantiate * them. (Can't check "ret" here, because it may * be misleading.) */ if (pipes[0] || pipes[1]) { /* * First, close up the gaps we punched in * the parameter list. */ for (pp = _pp = parms; *pp; pp++) if (*pp != hole) *_pp++ = *pp; *_pp = 0; /* * Re-instantiate the filter(s). This * CAN'T fail, because it is not mandatory * that filters handle cpi/lpi/etc. stuff. */ ret = insfilter( pipes, prs->request->input_type, output_type, pc->printer_type, pps->printer->name, parms, &(pc->flags) ); } } } /* * Save the filters, if any. Note: although "ret" can be * misleading, i.e. set to "fl_both" when there really aren't * any filters, the declaration of "pipes" ensured they'd be * zero if not set. */ if (ret == fl_both || ret == fl_slow) pc->slow = pipes[0]; if (ret == fl_both || ret == fl_fast) pc->fast = pipes[1]; if (ret != fl_none) pc->output_type = Strdup (output_type); /* * Wait until now to allocate storage for the cpi/etc. * stuff, to make life easier above. */ if (prs->cpi) prs->cpi = Strdup(prs->cpi); if (prs->lpi) prs->lpi = Strdup(prs->lpi); if (prs->plen) prs->plen = Strdup(prs->plen); if (prs->pwid) prs->pwid = Strdup(prs->pwid); if (parms) Free ((char *)parms); if (modes) freelist (modes); return ((ret != fl_none)); }