1
0
mirror of https://github.com/php/php-src.git synced 2026-04-07 16:13:32 +02:00

Clean up EXIF code and give up on extracting the embedded thumbnail for

now.  Will return to it when I find some real specs on it.
Also added a couple of missing copyright headers
This commit is contained in:
Rasmus Lerdorf
2000-05-29 16:34:19 +00:00
parent 949574d027
commit ebd9e89fcf
3 changed files with 153 additions and 611 deletions

View File

@@ -46,29 +46,6 @@
#include "ext/standard/php_string.h"
#include "ext/standard/info.h"
/*
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <ctype.h>
#ifdef PHP_WIN32
#include <process.h>
#include <io.h>
#define stat _stat
#else
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#endif
*/
typedef unsigned char uchar;
#ifndef TRUE
@@ -101,6 +78,14 @@ typedef struct {
double FocalplaneUnits;
int ExifImageWidth;
int MotorolaOrder;
int Orientation;
char GPSinfo[48];
int ISOspeed;
char ExifVersion[16];
char Copyright[32];
char Software[32];
char *Thumbnail;
int ThumbnailSize;
} ImageInfoType;
/* This structure is used to store a section of a Jpeg file. */
@@ -110,14 +95,6 @@ typedef struct {
unsigned Size;
} Section_t;
#if 0
int remove_thumbnails = FALSE;
int DoSubdirs = FALSE;
int ShowTags = 0; /* Do not show raw by default. */
int ShowStruct = 1; /* Show the built structure by default. */
#endif
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
@@ -147,22 +124,6 @@ PHP_MINFO_FUNCTION(exif) {
php_info_print_table_end();
}
/*
These macros are used to read the input file.
To reuse this code in another application, you might need to change these.
*/
/* Error exit handler */
/* #define ERREXIT(msg) (fprintf(stderr,"Error : %s\n", msg), exit(EXIT_FAILURE)) */
/*
void ERREXIT(char *msg)
{
fprintf(stderr,"Error : %s\n", msg);
fprintf(stderr,"in file '%s'\n",CurrentFile);
exit(EXIT_FAILURE);
}
*/
/*
JPEG markers consist of one or more 0xFF bytes, followed by a marker
code byte (which is not an FF). Here are the marker codes of interest
@@ -273,14 +234,6 @@ static void process_SOFn (ImageInfoType *ImageInfo, uchar *Data, int marker)
case M_SOF15: process = "Differential lossless, arithmetic coding"; break;
default: process = "Unknown"; break;
}
/*
if (ShowTags) {
printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
ImageInfo->Width, ImageInfo->Height, num_components, data_precision);
printf("JPEG process: %s\n", process);
}
*/
}
/*
@@ -309,12 +262,26 @@ static int ExifBytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
#define TAG_EXIF_OFFSET 0x8769
#define TAG_INTEROP_OFFSET 0xa005
#define TAG_COMPRESSION 0x0103
#define TAG_MAKE 0x010F
#define TAG_MODEL 0x0110
#define TAG_ORIENTATION 0x0112
#define TAG_SOFTWARE 0x0131
#define TAG_THUMBOFFSET 0x0201
#define TAG_THUMBSIZE 0x0202
#define TAG_COPYRIGHT 0x8298
#define TAG_EXPOSURETIME 0x829A
#define TAG_FNUMBER 0x829D
#define TAG_GPSINFO 0x8825
#define TAG_ISOSPEED 0x8827
#define TAG_EXIFVERSION 0x9000
#define TAG_SHUTTERSPEED 0x9201
#define TAG_APERTURE 0x9202
#define TAG_MAXAPERTURE 0x9205
@@ -331,7 +298,6 @@ static int ExifBytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
#define TAG_FOCALPLANEUNITS 0xa210
#define TAG_IMAGEWIDTH 0xA002
static const struct {
unsigned short Tag;
char *Desc;
@@ -451,27 +417,6 @@ static unsigned Get32u(void *Long, int MotorolaOrder)
return (unsigned)Get32s(Long, MotorolaOrder) & 0xffffffff;
}
#if 0
/* Display a number as one of its many formats */
static void PrintFormatNumber(void *ValuePtr, int Format)
{
switch(Format) {
case FMT_SBYTE:
case FMT_BYTE: printf("%02x ",*(uchar *)ValuePtr); break;
case FMT_USHORT: printf("%d\n",Get16u(ValuePtr)); break;
case FMT_ULONG:
case FMT_SLONG: printf("%d\n",Get32s(ValuePtr)); break;
case FMT_SSHORT: printf("%hd\n",(signed short)Get16u(ValuePtr)); break;
case FMT_URATIONAL:
case FMT_SRATIONAL:
printf("%d/%d\n",Get32s(ValuePtr), Get32s(4+(char *)ValuePtr)); break;
case FMT_SINGLE: printf("%f\n",(double)*(float *)ValuePtr); break;
case FMT_DOUBLE: printf("%f\n",*(double *)ValuePtr); break;
}
}
#endif
/* Evaluate number, be it int, rational, or float from directory. */
static double ConvertAnyFormat(void *ValuePtr, int Format, int MotorolaOrder)
{
@@ -522,6 +467,7 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
php_error(E_ERROR,"Illegally sized directory");
}
/*
if (ShowTags) {
printf("Directory with %d entries\n",NumDirEntries);
@@ -569,43 +515,7 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
*/
LastExifRefd = ValuePtr+ByteCount;
}
#if 0
if (ShowTags) {
/* Show tag name */
for (a=0;;a++) {
if (TagTable[a].Tag == 0) {
printf(" Unknown Tag %04x Value = ", Tag);
break;
}
if (TagTable[a].Tag == Tag) {
printf(" %s = ",TagTable[a].Desc);
break;
}
}
/* Show tag value. */
switch(Format) {
case FMT_UNDEFINED:
/* Undefined is typically an ascii string. */
case FMT_STRING:
/* String arrays printed without function call (different from int arrays) */
printf("\"");
for (a=0;a<ByteCount;a++) {
if (isprint((ValuePtr)[a])) {
putchar((ValuePtr)[a]);
}
}
printf("\"\n");
break;
default:
/* Handle arrays of numbers later (will there ever be?) */
PrintFormatNumber(ValuePtr, Format);
}
}
#endif
/* Extract useful components of tag */
switch(Tag) {
@@ -617,6 +527,30 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
strncpy(ImageInfo->CameraModel, ValuePtr, 63);
break;
case TAG_GPSINFO:
strncpy(ImageInfo->GPSinfo, ValuePtr, 47);
break;
case TAG_EXIFVERSION:
strncpy(ImageInfo->ExifVersion, ValuePtr, 15);
break;
case TAG_COPYRIGHT:
strncpy(ImageInfo->Copyright, ValuePtr, 31);
break;
case TAG_SOFTWARE:
strncpy(ImageInfo->Software, ValuePtr, 31);
break;
case TAG_ORIENTATION:
ImageInfo->Orientation = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->MotorolaOrder);
break;
case TAG_ISOSPEED:
ImageInfo->ISOspeed = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->MotorolaOrder);
break;
case TAG_DATETIME_ORIGINAL:
strncpy(ImageInfo->DateTime, ValuePtr, 19);
break;
@@ -740,7 +674,7 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
}
/*
rocess a EXIF marker
Process an EXIF marker
Describes all the drivel that most digital cameras include...
*/
static void process_EXIF (ImageInfoType *ImageInfo, char *CharBuf, unsigned int length, char *LastExifRefd)
@@ -752,12 +686,6 @@ static void process_EXIF (ImageInfoType *ImageInfo, char *CharBuf, unsigned int
ImageInfo->FocalplaneUnits = 0;
ImageInfo->ExifImageWidth = 0;
/*
if (ShowTags) {
printf("Exif header %d bytes long\n",length);
}
*/
{ /* Check the EXIF header component */
static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
if (memcmp(CharBuf+2, ExifHeader,6)) {
@@ -790,12 +718,6 @@ static void process_EXIF (ImageInfoType *ImageInfo, char *CharBuf, unsigned int
if (ImageInfo->FocalplaneXRes != 0) {
ImageInfo->CCDWidth = (float)(ImageInfo->ExifImageWidth * ImageInfo->FocalplaneUnits / ImageInfo->FocalplaneXRes);
}
/*
if (ShowTags) {
printf("Thunbnail size of Exif header: %d\n",length-(LastExifRefd-CharBuf));
}
*/
}
/* Parse the marker stream until SOS or EOI is seen; */
@@ -930,95 +852,6 @@ static int scan_JPEG_header (ImageInfoType *ImageInfo, FILE *infile, Section_t *
return TRUE;
}
#if 0
/* Command line parsing code */
static const char *progname; /* program name for error messages */
#endif
#if 0
/*
Show the collected image info, displaying camera F-stop and shutter speed
in a consistent and legible fashion.
*/
void ShowImageInfo(ImageInfoType *ImageInfo)
{
printf("File name : %s\n",ImageInfo->FileName);
printf("File size : %d bytes\n",ImageInfo->FileSize);
{
char Temp[20];
struct tm ts;
ts = *localtime(&ImageInfo->FileDateTime);
strftime(Temp, 20, "%Y:%m:%d %H:%M:%S", &ts);
printf("File date : %s\n",Temp);
}
if (ImageInfo->CameraMake[0]) {
printf("Camera make : %s\n",ImageInfo->CameraMake);
printf("Camera model : %s\n",ImageInfo->CameraModel);
}
if (ImageInfo->DateTime[0]) {
printf("Date/Time : %s\n",ImageInfo->DateTime);
}
printf("Resolution : %d x %d\n",ImageInfo->Width, ImageInfo->Height);
if (ImageInfo->IsColor == 0) {
printf("Color/bw : Black and white\n");
}
if (ImageInfo->FlashUsed >= 0) {
printf("Flash used : %s\n",ImageInfo->FlashUsed ? "Yes" :"No");
}
if (ImageInfo->FocalLength) {
printf("Focal length : %4.1fmm",(double)ImageInfo->FocalLength);
if (ImageInfo->CCDWidth) {
printf(" (35mm equivalent: %dmm)",
(int)(ImageInfo->FocalLength/ImageInfo->CCDWidth*35 + 0.5));
}
printf("\n");
}
if (ImageInfo->CCDWidth) {
printf("CCD Width : %5.2fm\n",(double)ImageInfo->CCDWidth);
}
if (ImageInfo->ExposureTime) {
printf("Exposure time:%6.3f s ",(double)ImageInfo->ExposureTime);
if (ImageInfo->ExposureTime <= 0.5) {
printf(" (1/%d)",(int)(0.5 + 1/ImageInfo->ExposureTime));
}
printf("\n");
}
if (ImageInfo->ApertureFNumber) {
printf("Aperture : f/%4.1f\n",(double)ImageInfo->ApertureFNumber);
}
if (ImageInfo->Distance) {
if (ImageInfo->Distance < 0) {
printf("Focus Dist. : Infinite\n");
} else {
printf("Focus Dist. :%5.2fm\n",(double)ImageInfo->Distance);
}
}
/* Print the comment. Print 'Comment:' for each new line of comment. */
if (ImageInfo->Comments[0]) {
int a,c;
printf("Comment : ");
for (a=0;a<200;a++) {
c = ImageInfo->Comments[a];
if (c == '\0') break;
if (c == '\n') {
printf("\nComment : ");
} else {
putchar(c);
}
}
printf("\n");
}
printf("\n");
}
#endif
/*
Discard read data.
*/
@@ -1083,80 +916,38 @@ int ReadJpegFile(ImageInfoType *ImageInfo, Section_t *Sections,
fclose(infile);
if (ret != FALSE) {
DiscardData(Sections, SectionsRead);
}
return ret;
}
#if 0
/*
Remove exif thumbnail
*/
int RemoveThumbnail(Section_t *Sections)
{
int a;
for (a=0;a<SectionsRead-1;a++) {
if (Sections[a].Type == M_EXIF) {
/* Truncate the thumbnail section of the exif. */
unsigned int Newsize = LastExifRefd-(char *)Sections[a].Data;
if (Sections[a].Size == Newsize) return FALSE; /* Thumbnail already gonne. */
Sections[a].Size = Newsize;
Sections[a].Data[0] = (uchar)(Newsize >> 8);
Sections[a].Data[1] = (uchar)Newsize;
return TRUE;
}
}
/* Not an exif image. Don't know how to get rid of thumbnails. */
return FALSE;
}
#endif
#if 0
/*
Write image data back to disk.
*/
void WriteJpegFile(char *FileName, Section_t *Sections, int *SectionsRead, int *HaveAll)
{
FILE *outfile;
int a;
if (!*HaveAll) {
php_error(E_ERROR,"Can't write back - didn't read all");
}
outfile = V_FOPEN(FileName,"wb");
if (outfile == NULL) {
php_error(E_ERROR,"Could not open file for write");
}
/* Initial static jpeg marker. */
fputc(0xff,outfile);
fputc(0xd8,outfile);
/* Write all the misc sections */
for (a=0;a<*SectionsRead-1;a++) {
fputc(0xff,outfile);
fputc(Sections[a]->Type, outfile);
fwrite(Sections[a]->Data, Sections[a]->Size, 1, outfile);
}
/* Write the remaining image data. */
fwrite(Sections[a]->Data, Sections[a]->Size, 1, outfile);
fclose(outfile);
}
#endif
int php_read_jpeg_exif(ImageInfoType *ImageInfo, char *FileName, int ReadAll) {
PHPAPI int php_read_jpeg_exif(ImageInfoType *ImageInfo, char *FileName, int ReadAll) {
Section_t Sections[20];
int SectionsRead;
char *LastExifRefd=NULL;
int ret;
int ret, i;
int thumbsize=0;
ImageInfo->MotorolaOrder = 0;
ret = ReadJpegFile(ImageInfo, Sections, &SectionsRead, FileName, ReadAll, LastExifRefd);
/*
* Thought this might pick out the embedded thumbnail, but it doesn't work.
for (i=0;i<SectionsRead-1;i++) {
if (Sections[i].Type == M_EXIF) {
thumbsize = Sections[i].Size;
if(thumbsize>0) {
ImageInfo->Thumbnail = emalloc(thumbsize+5);
ImageInfo->ThumbnailSize = thumbsize;
ImageInfo->Thumbnail[0] = 0xff;
ImageInfo->Thumbnail[1] = 0xd8;
ImageInfo->Thumbnail[2] = 0xff;
memcpy(ImageInfo->Thumbnail+4, Sections[i].Data, thumbsize+4);
}
}
}
*/
if (ret != FALSE) {
DiscardData(Sections, &SectionsRead);
}
return(ret);
}
@@ -1168,6 +959,9 @@ PHP_FUNCTION(read_exif_data) {
ImageInfoType ImageInfo;
char tmp[64];
ImageInfo.Thumbnail = NULL;
ImageInfo.ThumbnailSize = 0;
if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE)
WRONG_PARAM_COUNT;
@@ -1229,341 +1023,39 @@ PHP_FUNCTION(read_exif_data) {
if(ImageInfo.CCDWidth) {
add_assoc_double(return_value,"CCDWidth",ImageInfo.CCDWidth);
}
if(ImageInfo.Orientation) {
add_assoc_long(return_value,"Orientation",ImageInfo.Orientation);
}
if (ImageInfo.GPSinfo[0]) {
add_assoc_string(return_value,"GPSinfo",ImageInfo.GPSinfo,1);
}
if(ImageInfo.ISOspeed) {
add_assoc_long(return_value,"ISOspeed",ImageInfo.ISOspeed);
}
if (ImageInfo.ExifVersion[0]) {
add_assoc_string(return_value,"ExifVersion",ImageInfo.ExifVersion,1);
}
if (ImageInfo.Copyright[0]) {
add_assoc_string(return_value,"Copyright",ImageInfo.Copyright,1);
}
if (ImageInfo.Software[0]) {
add_assoc_string(return_value,"Software",ImageInfo.Software,1);
}
if(ImageInfo.Comments[0]) {
add_assoc_string(return_value,"Comments",ImageInfo.Comments,1);
}
if(ImageInfo.ThumbnailSize) {
add_assoc_stringl(return_value,"Thumbnail",ImageInfo.Thumbnail,ImageInfo.ThumbnailSize,1);
add_assoc_long(return_value,"ThumbnailSize",ImageInfo.ThumbnailSize);
efree(ImageInfo.Thumbnail);
}
}
#if 0
#endif
/*
Do selected operations to one file at a time.
*/
void ProcessFile(char *FileName)
{
int MayModify = FALSE;
int Modified = FALSE;
ImageInfoType ImageInfo;
Section_t Sections[20];
int SectionsRead, HaveAll;
char *LastExifRefd;
/* FilesMatched = TRUE; / * Turns off complaining that nothing matched. */
/*
if (remove_thumbnails) {
MayModify = TRUE;
}
*/
if (!ReadJpegFile(&ImageInfo, &Sections, &SectionsRead, &HaveAll, FileName, MayModify, LastExifRefd)) return;
ShowImageInfo(&ImageInfo);
/*
if (remove_thumbnails) {
if (RemoveThumbnail(&Sections, SectionsRead)) {
Modified = TRUE;
}
}
*/
if (Modified) {
char BackupName[400];
strcpy(BackupName, FileName);
strcat(BackupName, ".old");
/* Remove any .old file name that may pre-exist */
unlink(BackupName);
/* Rename the old file. */
rename(FileName, BackupName);
/* Write the new file. */
WriteJpegFile(FileName);
/* Now that we are done, remove original file. */
unlink(BackupName);
}
DiscardData(&Sections, &SectionsRead, &HaveAll);
}
#endif
#if 0
/* complain about bad state of the command line. */
static void Usage (void)
{
fprintf(stderr,"Program for extracting Digicam setting information from Exif Jpeg headers\n"
"used by most Digital Cameras. v0.9 Matthias Wandel, April 2000.\n"
"http://www.sentex.net/~mwandel/jhead mwandel@sentex.net\n"
"\n");
fprintf(stderr,"Usage: %s [options] files\n", progname);
fprintf(stderr,"Where:\n"
"[otpions] are:\n"
" -t --> Remove exif thumbnails from exif files\n"
" -r --> Recursive.\n"
" -h --> help (this text)\n"
" -v --> even more verbose output\n"
"files --> path/filenames with or without widlcards\n"
);
exit(EXIT_FAILURE);
}
#endif
/* Checking of an extension. */
int ExtCheck(char *Ext, char *Pattern)
{
for(;;Ext++,Pattern++) {
if (*Ext == *Pattern) {
if (*Ext == '\0') return 0; /* Matches. */
continue;
}
if (*Ext > 'A' && *Ext <= 'Z') {
if (*Ext+'a'-'A' == *Pattern) continue;
}
return 1; /* Differs. */
}
}
#if 0
/* Handle a pattern, possibly using subdirectories... (Linux) */
#ifndef PHP_WIN32
static void HandleSubpath(char *Path)
{
DIR *dirpt;
char DirName[200];
int a;
struct stat filestat;
if (stat(Path, &filestat)) {
printf("Error on '%s'\n",Path);
return;
}
if(!S_ISDIR(filestat.st_mode)) {
/* This is a file, not a directory. */
ProcessFile(Path);
return;
}
strcpy(DirName,Path);
a=strlen(DirName);
if (DirName[a-1] != '/') {
/* Make sure it ends with '/' */
DirName[a] = '/';
DirName[a+1] = '\0';
}
dirpt = opendir(DirName);
if (dirpt == NULL) {
printf("Could not read directory: %s",strerror(errno));
return;
}
for (;;) {
struct dirent *entry;
static char FullPath[400];
entry = readdir(dirpt);
if (entry == NULL) break;
strcpy(FullPath, DirName);
strcat(FullPath, entry->d_name);
if (stat(FullPath, &filestat)) {
printf("Error on '%s'\n",FullPath);
continue;
}
if(!S_ISREG(filestat.st_mode)) continue; /* Not a regular file. Ignore. */
a=strlen(entry->d_name);
if (a < 5) continue; /* Too short a name to make sense (looking for .jpg extension) */
if (ExtCheck(entry->d_name+a-5, ".jpeg") != 0
&& ExtCheck(entry->d_name+a-4, ".jpg") != 0) {
/* Its not .jpg or .jpeg. */
continue;
}
ProcessFile(FullPath);
}
closedir(dirpt);
/*
Do subdirectories after doing the current directory.
This necessitates reading the directory twice.
*/
if (DoSubdirs) {
dirpt = opendir(DirName);
for (;;) {
struct dirent *entry;
static char FullPath[400];
entry = readdir(dirpt);
if (entry == NULL) break;
strcpy(FullPath, DirName);
strcat(FullPath, entry->d_name);
if (stat(FullPath, &filestat)) {
printf("Error on '%s'\n",FullPath);
continue;
}
if(!S_ISDIR(filestat.st_mode)) continue; /* Not a directory. */
if (entry->d_name[0] == '.' || entry->d_name[0] == '_') {
/* Skip strange directory names (I use these for thumbnails) */
} else {
HandleSubpath(FullPath);
}
}
closedir(dirpt);
}
}
#else
/* Handle a pattern, possibly using subdirectories... (Windows) */
static void HandleSubpath(char *Path)
{
struct _finddata_t finddata;
long find_handle;
char ThisPattern[200];
int a;
strcpy(ThisPattern,Path);
if (DoSubdirs) {
strcat(ThisPattern,"\\*");
}
find_handle = _findfirst(ThisPattern, &finddata);
if (find_handle == -1) {
fprintf(stderr, "Error: No file matches '%s'\n",Path);
}
for (;;) {
static char CombinedPath[400];
if (find_handle == -1) break;
if (finddata.attrib & _A_SUBDIR) goto nextfile; /* Its a subdirectory. */
a=strlen(finddata.name);
if (a < 5) goto nextfile; /* Too short a name to contain '.jpg' */
if (ExtCheck(finddata.name+a-5, ".jpeg") != 0
&& ExtCheck(finddata.name+a-4, ".jpg") != 0) {
/* Its not .jpg or .jpeg. */
goto nextfile;
}
/*
This whole area is really gross, but below hack makes it so that
if I drag a single file on it on the desktop, it will find it
using the given paths.
*/
strcpy(CombinedPath, Path);
a=strlen(Path);
if (!DoSubdirs) {
for(;a;) {
a--;
if (!a) {
CombinedPath[0] = 0;
break;
}
if (CombinedPath[a] == '\\') {
CombinedPath[a+1] = 0;
break;
}
}
} else {
strcat(CombinedPath, "\\");
}
strcat(CombinedPath, finddata.name);
ProcessFile(CombinedPath);
nextfile:
if (_findnext(find_handle, &finddata) != 0) break;
}
_findclose(find_handle);
if (DoSubdirs) {
find_handle = _findfirst(ThisPattern, &finddata);
for (;;) {
if (find_handle == -1) break;
if (finddata.attrib & _A_SUBDIR) {
/* Its a subdirectory. */
if (finddata.name[0] == '.' || finddata.name[0] == '_') {
/* Skip strange directory names (I use thes for thumbnails) */
} else {
strcpy(ThisPattern, Path);
strcat(ThisPattern, "\\");
strcat(ThisPattern, finddata.name);
HandleSubpath(ThisPattern);
}
}
if (_findnext(find_handle, &finddata) != 0) break;
}
_findclose(find_handle);
}
}
#endif
#endif
#if 0
int main (int argc, char **argv)
{
int argn;
char *arg;
progname = argv[0];
for (argn=1;argn<argc;argn++) {
arg = argv[argn];
if (arg[0] != '-') break; /* Filenames from here on. */
if (!strcmp(arg,"-v")) {
ShowTags = TRUE;
} else if (!strcmp(arg,"-t")) {
remove_thumbnails = TRUE;
} else if (!strcmp(arg,"-r")) {
DoSubdirs = TRUE;
} else if (!strcmp(arg,"-h")) {
Usage();
} else {
printf("Argument '%s' not understood\n",arg);
Usage();
}
}
if (argn == argc) {
fprintf(stderr,"Error: Must supply a file name\n");
Usage();
}
for (;argn<argc;argn++) {
FilesMatched = FALSE;
HandleSubpath(argv[argn]);
if (!FilesMatched) {
fprintf(stderr, "Error: No files matched '%s'\n",argv[argn]);
}
}
return EXIT_SUCCESS;
}
#endif
#endif
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/

View File

@@ -1,3 +1,21 @@
/*
+----------------------------------------------------------------------+
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: |
| |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "SAPI.h"
#include "rfc1867.h"
@@ -28,3 +46,10 @@ int php_startup_sapi_content_types(void)
sapi_register_default_post_reader(php_default_post_reader);
return SUCCESS;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/

View File

@@ -1,3 +1,21 @@
/*
+----------------------------------------------------------------------+
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: |
| |
+----------------------------------------------------------------------+
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
@@ -556,3 +574,10 @@ main(void)
}
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/