<isol>

/* Definition der Form der GhostScript Kommandozeile */
#define CPGSCALL "%s -q -dCompatibilityLevel=%s \
                  -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
		  -sOutputFile=%s -c save pop -f %s"

/* ...und los geht es... */
int main(int argc, char *argv[]) {
  char *dirname, *spoolfile, *outfile, *gscall,
       title[BUFSIZE]="";
  int size;
  struct passwd *passwd;

/* Zunächst wird die allgemeine Verzeichnisstruktur
   erstellt. Bei einem Problem wird -1 zurückgegeben */
  umask(0000);
  if (init()) return -1;
  
/* Wenn CUPS ein Backend nur mit seinem Namen aufruft,
   muß es sich identifizieren und 0 zurückgeben */  
  if (argc==1) {
    printf("file cups-pdf:/ \"PDF Printer\" "
           "\"Virtual Printer\"\n"); 
    return 0;
  }
  
/* Weniger als 6 oder mehr als 7 Argumente (inkl.
   Backendname) sind nicht vorgesehen - Fehler */  
  if (argc<6 || argc>7) {
    fputs("Usage: cups-pdf job-id user title copies "
          "options [file]\n", stderr);
      return 0;
  }

/* Feststellung, ob der Benutzer bekannt ist oder ggf.
   ob eine anonyme PDF Erezugung erlaubt ist. Erzeugung
   der Benutzerverzeichnisse. */
  passwd=getpwnam(argv[2]);
  if (passwd == NULL) {
    if (strlen(CPANONUSER)) {
      passwd=getpwnam(CPANONUSER);
      if (passwd == NULL) {
        return -2;
      }
      size=strlen(CPOUT)+strlen(CPANONDIRNAME)+4;
      dirname=calloc(size, sizeof(char));
      if (dirname == NULL) return -2; 
      snprintf(dirname, size, "%s/%s", CPOUT,
               CPANONDIRNAME);
    }	       
    else
      return 0;
  } 
  else {
    umask(0077);
    size=strlen(CPOUT)+strlen(passwd->pw_name)+4;
    dirname=calloc(size, sizeof(char));
    if (dirname == NULL) return -2;  
    snprintf(dirname, size, "%s/%s", CPOUT,
             passwd->pw_name);
  }
  if (prepareuser(passwd, dirname)) return -2;
  
/* Festlegung eines eindeutigen Spooldateinamens */  
  size=strlen(CPSPOOL)+22;
  spoolfile=calloc(size, sizeof(char));
  if (spoolfile == NULL) {
    free(dirname);
    return -3;
  }
  snprintf(spoolfile, size, "%s/cups2pdf-%i", CPSPOOL,
           (int) getpid());

/* Bei 6 Argumenten folgt die zu konvertierende Datei
   über die Standardeingabe */
  if (argc == 6) {
    if (preparespoolfile(stdin, spoolfile, title)) {
      free(dirname);
      free(spoolfile);
      return -4;
    }
  }
/* Bei 7 Argumenten stehen die Daten in der Datei,
   die im 7. Argument genannt ist */  
  else {
    if (preparespoolfile(fopen(argv[6], "r"),
        spoolfile, title)) {
      free(dirname);
      free(spoolfile);
      return -4;
    }
  }  

/* Erzeugung des endgültigen Namens der PDF Datei */
  size=strlen(dirname)+strlen(title)+6;
  outfile=calloc(size, sizeof(char));
  if (outfile == NULL) {
    free(dirname);
    free(spoolfile);
    return -5;
  }
  snprintf(outfile, size, "%s/%s.pdf", dirname, title);

/* Hier wird die GhostScript Kommandozeile zusammen-
   gebastelt */
  size=strlen(CPGSCALL)+strlen(CPGHOSTSCRIPT)+
       strlen(CPPDFVER)+strlen(outfile)+
       strlen(spoolfile)+6;
  gscall=calloc(size, sizeof(char));
  if (gscall == NULL) {
    free(dirname);
    free(spoolfile);
    free(outfile);
    return -6;
  }
  snprintf(gscall, size, CPGSCALL, CPGHOSTSCRIPT,
           CPPDFVER, outfile, spoolfile);

/* Jetzt die Ausgabedatei ggf. entfernen... */
  unlink(outfile);
/* ...GhostScript aufrufen...*/    
  system(gscall);
/* ...und die Spooldatei löschen */  
  unlink(spoolfile);

/* Abschließend wird noch der Eigentümer gesetzt */  
  if (chown(outfile, passwd->pw_uid, passwd->pw_gid)) {
    free(dirname);
    free(spoolfile);
    free(outfile);
    free(gscall);
    return -7;
  }

/* Allen Speicher freigeben und ... fertig! */  
  free(dirname);
  free(spoolfile);
  free(outfile);
  free(gscall);
  
  return 0;
} 
