217 строки
6.0 KiB
C
217 строки
6.0 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
/*
|
|
*
|
|
* routines to sort an array of file objects
|
|
* uses qsort alg
|
|
*
|
|
* Designed and implemented by Lou Montulli '94
|
|
*/
|
|
|
|
#include "mkutils.h"
|
|
#include "mkfsort.h"
|
|
#include "mkgeturl.h"
|
|
|
|
#ifdef PROFILE
|
|
#pragma profile on
|
|
#endif
|
|
|
|
PRIVATE int net_file_sort_method = SORT_BY_NAME;
|
|
|
|
/* print a text string in place of the NET_FileEntryInfo special_type int */
|
|
PUBLIC char *
|
|
NET_PrintFileType(int special_type)
|
|
{
|
|
switch(special_type)
|
|
{
|
|
case NET_FILE_TYPE:
|
|
return("FILE");
|
|
case NET_DIRECTORY:
|
|
return("DIRECTORY");
|
|
case NET_SYM_LINK:
|
|
return("SYMBOLIC-LINK");
|
|
case NET_SYM_LINK_TO_DIR:
|
|
return("SYM-DIRECTORY");
|
|
case NET_SYM_LINK_TO_FILE:
|
|
return("SYM-FILE");
|
|
default:
|
|
PR_ASSERT(0);
|
|
return("FILE");
|
|
}
|
|
}
|
|
|
|
PRIVATE void
|
|
NET_SetFileSortMethod(int method)
|
|
{
|
|
net_file_sort_method = method;
|
|
}
|
|
|
|
MODULE_PRIVATE void NET_FreeEntryInfoStruct(NET_FileEntryInfo *entry_info)
|
|
{
|
|
if(entry_info)
|
|
{
|
|
FREEIF(entry_info->filename);
|
|
/* free the struct */
|
|
PR_Free(entry_info);
|
|
}
|
|
}
|
|
|
|
MODULE_PRIVATE NET_FileEntryInfo * NET_CreateFileEntryInfoStruct (void)
|
|
{
|
|
NET_FileEntryInfo * new_entry = PR_NEW(NET_FileEntryInfo);
|
|
|
|
if(!new_entry)
|
|
return(NULL);
|
|
|
|
memset(new_entry, 0, sizeof(NET_FileEntryInfo));
|
|
|
|
new_entry->permissions = -1;
|
|
|
|
return(new_entry);
|
|
|
|
}
|
|
|
|
/* This function is used as a comparer function for the Qsort routine.
|
|
* It uses a function FE_FileSortMethod() to determine the
|
|
* field to sort on.
|
|
*
|
|
*/
|
|
PRIVATE int
|
|
NET_CompareFileEntryInfoStructs (const void *ent2, const void *ent1)
|
|
{
|
|
int status;
|
|
const NET_FileEntryInfo *entry1 = *(NET_FileEntryInfo **) ent1;
|
|
const NET_FileEntryInfo *entry2 = *(NET_FileEntryInfo **) ent2;
|
|
|
|
if(!entry1 || !entry2)
|
|
return(-1);
|
|
|
|
switch(net_file_sort_method)
|
|
{
|
|
case SORT_BY_SIZE:
|
|
/* both equal or both 0 */
|
|
if(entry1->size == entry2->size)
|
|
return(PL_strcmp(entry2->filename, entry1->filename));
|
|
else
|
|
if(entry1->size > entry2->size)
|
|
return(-1);
|
|
else
|
|
return(1);
|
|
/* break; NOT NEEDED */
|
|
case SORT_BY_TYPE:
|
|
if(entry1->cinfo && entry1->cinfo->desc &&
|
|
entry2->cinfo && entry2->cinfo->desc)
|
|
{
|
|
status = PL_strcmp(entry1->cinfo->desc, entry2->cinfo->desc);
|
|
if(status)
|
|
return(status);
|
|
/* else fall to filename comparison */
|
|
}
|
|
return (PL_strcmp(entry2->filename, entry1->filename));
|
|
/* break; NOT NEEDED */
|
|
case SORT_BY_DATE:
|
|
if(entry1->date == entry2->date)
|
|
return(PL_strcmp(entry2->filename, entry1->filename));
|
|
else
|
|
if(entry1->size > entry2->size)
|
|
return(-1);
|
|
else
|
|
return(1);
|
|
/* break; NOT NEEDED */
|
|
case SORT_BY_NAME:
|
|
default:
|
|
return (PL_strcmp(entry2->filename, entry1->filename));
|
|
}
|
|
}
|
|
|
|
/* sort the files
|
|
*/
|
|
MODULE_PRIVATE void
|
|
NET_DoFileSort(SortStruct * sort_list)
|
|
{
|
|
NET_DoSort(sort_list, NET_CompareFileEntryInfoStructs);
|
|
}
|
|
|
|
#define PD_PUTS(s) \
|
|
do { \
|
|
if(status > -1) \
|
|
status = (*stream->put_block)(stream, s, PL_strlen(s)); \
|
|
} while(0)
|
|
|
|
PUBLIC int
|
|
NET_PrintDirectory(SortStruct **sort_base, NET_StreamClass * stream, char * path, URL_Struct *URL_s)
|
|
{
|
|
NET_FileEntryInfo * file_entry;
|
|
char out_buf[3096];
|
|
char *esc_path = NET_Escape(path, URL_PATH);
|
|
int i;
|
|
int status=0;
|
|
|
|
NET_DoFileSort(*sort_base);
|
|
|
|
/* emit 300: URL CRLF */
|
|
PL_strcpy(out_buf, "300: ");
|
|
PD_PUTS(out_buf);
|
|
PR_snprintf(out_buf, sizeof(out_buf), URL_s->address);
|
|
PD_PUTS(out_buf);
|
|
|
|
PL_strcpy(out_buf, CRLF);
|
|
PD_PUTS(out_buf);
|
|
|
|
/* emit 200: Filename Size Content-Type File-type Last-Modified */
|
|
PL_strcpy(out_buf, "200: Filename Content-Length Content-Type File-type Last-Modified"CRLF);
|
|
PD_PUTS(out_buf);
|
|
|
|
for(i=0; status > -1 && (file_entry = (NET_FileEntryInfo *)
|
|
NET_SortRetrieveNumber(*sort_base, i)) != 0;
|
|
i++)
|
|
{
|
|
|
|
|
|
char * esc_time = NET_Escape(ctime(&file_entry->date), URL_XALPHAS);
|
|
|
|
strtok(file_entry->filename, "/");
|
|
PR_snprintf(out_buf, sizeof(out_buf), "201: %s %ld %s %s %s"CRLF,
|
|
file_entry->filename,
|
|
file_entry->size,
|
|
file_entry->special_type == NET_DIRECTORY ? "application/http-index-format" :
|
|
file_entry->cinfo ? file_entry->cinfo->type : TEXT_PLAIN,
|
|
file_entry->special_type == NET_DIRECTORY ? "Directory" : "File",
|
|
esc_time);
|
|
|
|
PR_Free(esc_time);
|
|
|
|
PD_PUTS(out_buf);
|
|
|
|
NET_FreeEntryInfoStruct(file_entry);
|
|
}
|
|
|
|
NET_SortFree(*sort_base);
|
|
*sort_base = 0;
|
|
|
|
PR_FREEIF(esc_path);
|
|
if(status < 0)
|
|
return(status);
|
|
return(MK_DATA_LOADED);
|
|
}
|
|
|
|
#ifdef PROFILE
|
|
#pragma profile off
|
|
#endif
|
|
|