Exemple #1
0
XDG_PARSED_FILE *XDG_ParseDesktopFile(int fd)
{
    struct stat stats;
    XDG_PARSED_FILE *parsed = NULL;
    PARSED_ENTRY **curr_entry;
    PARSED_GROUP **curr_group;
    BOOL is_in_group = FALSE;
    
    int pos = 0;
    
    if (fstat(fd, &stats) == -1) goto failed;
    parsed = SHAlloc(sizeof(XDG_PARSED_FILE));
    if (parsed == NULL) goto failed;
    parsed->groups = NULL;
    parsed->head_comments = NULL;
    parsed->contents = SHAlloc(stats.st_size+1);
    if (parsed->contents == NULL) goto failed;
    
    curr_entry = &parsed->head_comments;
    curr_group = &parsed->groups;
    
    if (read(fd, parsed->contents, stats.st_size) == -1) goto failed;
    parsed->contents[stats.st_size] = 0;

    while (pos < stats.st_size)
    {
        PARSED_ENTRY statement;
        int type, size;

        size = parse_line(parsed->contents + pos, &statement, &type);
        if (size == -1) goto failed;
        if (size == 0)
            break;
        pos += size;
        
        switch (type)
        {
            case LINE_GROUP:
            {
                PARSED_GROUP *group = SHAlloc(sizeof(PARSED_GROUP));
                if (group == NULL) goto failed;
                is_in_group = TRUE;
                
                group->name = statement.name;
                group->entries = NULL;
                group->next = NULL;
                *curr_group = group;
                curr_group = &group->next;
                curr_entry = &group->entries;
                break;
            }

            case LINE_ENTRY:
                if (!is_in_group) goto failed;
                /* fall through */
            case LINE_COMMENT:
            {
                PARSED_ENTRY *new_stat = SHAlloc(sizeof(PARSED_ENTRY));
                if (new_stat == NULL) goto failed;
                *new_stat = statement;
                new_stat->next = NULL;
                *curr_entry = new_stat;
                curr_entry = &new_stat->next;
                break;
            }
        }
    }
    return parsed;
    
failed:
    XDG_FreeParsedFile(parsed);
    return NULL;
}
Exemple #2
0
static HRESULT TRASH_GetDetails(const TRASH_BUCKET *bucket, LPCSTR filename, WIN32_FIND_DATAW *data)
{
    LPSTR path = NULL;
    XDG_PARSED_FILE *parsed = NULL;
    char *original_file_name = NULL;
    char *deletion_date = NULL;
    int fd = -1;
    struct stat stats;
    HRESULT ret = S_FALSE;
    LPWSTR original_dos_name;
    int suffix_length = lstrlenA(trashinfo_suffix);
    int filename_length = lstrlenA(filename);
    int files_length = lstrlenA(bucket->files_dir);
    int path_length = max(lstrlenA(bucket->info_dir), files_length);
    
    path = SHAlloc(path_length + filename_length + 1);
    if (path == NULL) return E_OUTOFMEMORY;
    wsprintfA(path, "%s%s", bucket->files_dir, filename);
    path[path_length + filename_length - suffix_length] = 0;  /* remove the '.trashinfo' */    
    if (lstat(path, &stats) == -1)
    {
        ERR("Error accessing data file for trashinfo %s (errno=%d)\n", filename, errno);
        goto failed;
    }
    
    wsprintfA(path, "%s%s", bucket->info_dir, filename);
    fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        ERR("Couldn't open trashinfo file %s (errno=%d)\n", path, errno);
        goto failed;
    }
    
    parsed = XDG_ParseDesktopFile(fd);
    if (parsed == NULL)
    {
        ERR("Parse error in trashinfo file %s\n", path);
        goto failed;
    }
    
    original_file_name = XDG_GetStringValue(parsed, trashinfo_group, "Path", XDG_URLENCODE);
    if (original_file_name == NULL)
    {
        ERR("No 'Path' entry in trashinfo file\n");
        goto failed;
    }
    
    ZeroMemory(data, sizeof(*data));
    data->nFileSizeHigh = (DWORD)((LONGLONG)stats.st_size>>32);
    data->nFileSizeLow = stats.st_size & 0xffffffff;
    RtlSecondsSince1970ToTime(stats.st_mtime, (LARGE_INTEGER *)&data->ftLastWriteTime);
    
    original_dos_name = wine_get_dos_file_name(original_file_name);
    if (original_dos_name != NULL)
    {
        lstrcpynW(data->cFileName, original_dos_name, MAX_PATH);
        SHFree(original_dos_name);
    }
    else
    {
        /* show only the file name */
        char *file = strrchr(original_file_name, '/');
        if (file == NULL)
            file = original_file_name;
        MultiByteToWideChar(CP_UNIXCP, 0, file, -1, data->cFileName, MAX_PATH);
    }
    
    deletion_date = XDG_GetStringValue(parsed, trashinfo_group, "DeletionDate", 0);
    if (deletion_date)
    {
        struct tm del_time;
        time_t del_secs;
        
        sscanf(deletion_date, "%d-%d-%dT%d:%d:%d",
            &del_time.tm_year, &del_time.tm_mon, &del_time.tm_mday,
            &del_time.tm_hour, &del_time.tm_min, &del_time.tm_sec);
        del_time.tm_year -= 1900;
        del_time.tm_mon--;
        del_time.tm_isdst = -1;
        del_secs = mktime(&del_time);
        
        RtlSecondsSince1970ToTime(del_secs, (LARGE_INTEGER *)&data->ftLastAccessTime);
    }
    
    ret = S_OK;
failed:
    SHFree(path);
    SHFree(original_file_name);
    SHFree(deletion_date);
    if (fd != -1)
        close(fd);
    XDG_FreeParsedFile(parsed);
    return ret;
}