00001
00002
00003 #include "common.h"
00004 #include "errabort.h"
00005 #include "cheapcgi.h"
00006 #include "pipeline.h"
00007 #include "textOut.h"
00008
00009 static char const rcsid[] = "$Id: textOut.c,v 1.3 2006/08/04 06:00:20 markd Exp $";
00010
00011 static void textOutWarnHandler(char *format, va_list args)
00012
00013 {
00014 char *hLine =
00015 "---------------------------------------------------------------------------\n";
00016 if (format != NULL) {
00017 fflush(stdout);
00018 fprintf(stdout, "%s", hLine);
00019 vfprintf(stdout, format, args);
00020 fprintf(stdout, "\n");
00021 fprintf(stdout, "%s", hLine);
00022 }
00023 }
00024
00025 static void textOutAbortHandler()
00026
00027 {
00028 exit(-1);
00029 }
00030
00031 static char *getCompressSuffix(char *compressType)
00032
00033 {
00034 static char *gzipSuffix = ".gz";
00035 static char *compressSuffix = ".Z";
00036 static char *bz2Suffix = ".bz2";
00037 static char *zipSuffix = ".zip";
00038 if (sameWord(compressType, textOutCompressGzip))
00039 return gzipSuffix;
00040 else if (sameWord(compressType, textOutCompressCompress))
00041 return compressSuffix;
00042 else if (sameWord(compressType, textOutCompressBzip2))
00043 return bz2Suffix;
00044 else if (sameWord(compressType, textOutCompressZip))
00045 return zipSuffix;
00046 else
00047 errAbort("getCompressSuffix: Unsupported textOutCompress type %s",
00048 compressType);
00049 return NULL;
00050 }
00051
00052 static char **getCompressor(char *compressType)
00053
00054 {
00055 static char *GZ_WRITE[] = {"gzip", "-qc", NULL};
00056 static char *Z_WRITE[] = {"compress", "-c", NULL};
00057 static char *BZ2_WRITE[] = {"bzip2", "-qzc", NULL};
00058 static char *ZIP_WRITE[] = {"zip", "-q", NULL};
00059
00060 if (sameWord(compressType, textOutCompressGzip))
00061 return GZ_WRITE;
00062 else if (sameWord(compressType, textOutCompressCompress))
00063 return Z_WRITE;
00064 else if (sameWord(compressType, textOutCompressBzip2))
00065 return BZ2_WRITE;
00066 else if (sameWord(compressType, textOutCompressZip))
00067 return ZIP_WRITE;
00068 else
00069 errAbort("getCompressor: Unsupported textOutCompress type %s",
00070 compressType);
00071 return NULL;
00072 }
00073
00074 static void cleanEnvVars(char *compressType)
00075
00076
00077 {
00078 if (sameWord(compressType, textOutCompressGzip))
00079 {
00080 unsetenv("GZIP");
00081 unsetenv("GZIP_OPT");
00082 }
00083 else if (sameWord(compressType, textOutCompressCompress))
00084 {
00085
00086 }
00087 else if (sameWord(compressType, textOutCompressBzip2))
00088 {
00089 unsetenv("BZIP");
00090 unsetenv("BZIP2");
00091 }
00092 else if (sameWord(compressType, textOutCompressZip))
00093 {
00094 unsetenv("ZIPOPT");
00095 }
00096 else
00097 {
00098 errAbort("cleanEnvVars: Unsupported textOutCompress type %s",
00099 compressType);
00100 }
00101 }
00102
00103
00104 struct pipeline *textOutInit(char *fileName, char *compressType)
00105
00106
00107
00108
00109
00110 {
00111 struct pipeline *compressPipeline = NULL;
00112
00113 trimSpaces(fileName);
00114 if (isEmpty(fileName))
00115 {
00116 printf("Content-Type: text/plain\n\n");
00117 }
00118 else if (isEmpty(compressType) || sameWord(compressType, textOutCompressNone))
00119 {
00120 printf("Content-Type: application/octet-stream\n");
00121 printf("Content-Disposition: attachment; filename=%s\n\n", fileName);
00122 }
00123 else
00124 {
00125 char *suffix = getCompressSuffix(compressType);
00126
00127 printf("Content-Type: application/x-%s\n", compressType);
00128 if (endsWith(fileName, suffix))
00129 printf("Content-Disposition: attachment; filename=%s\n\n", fileName);
00130 else
00131 printf("Content-Disposition: attachment; filename=%s%s\n\n",
00132 fileName, suffix);
00133
00134
00135 fflush(stdout);
00136
00137
00138 cleanEnvVars(compressType);
00139
00140
00141 compressPipeline = pipelineOpen1(getCompressor(compressType),
00142 pipelineWrite, NULL, NULL);
00143 if (-1 == dup2(pipelineFd(compressPipeline), STDOUT_FILENO))
00144 errnoAbort("dup2(pipelineFd %d, stdout %d) failed in textOpen()",
00145 pipelineFd(compressPipeline), STDOUT_FILENO);
00146 }
00147 pushWarnHandler(textOutWarnHandler);
00148 pushAbortHandler(textOutAbortHandler);
00149 return(compressPipeline);
00150 }
00151
00152 void textOutClose(struct pipeline **pCompressPipeline)
00153
00154
00155 {
00156 if (pCompressPipeline && *pCompressPipeline)
00157 {
00158 fflush(stdout);
00159 fclose(stdout);
00160 pipelineWait(*pCompressPipeline);
00161 pipelineFree(pCompressPipeline);
00162 }
00163 }
00164