Trove hackfest work with appropriate copyright notices and licence files added
[hurd/trovefs.git] / s3.c
1 /*
2  * Copyright (C) 2013  Steven McDonald <steven@steven-mcdonald.id.au>
3  *
4  * This program is free software. It comes without any warranty, to the
5  * extent permitted by applicable law. You can redistribute it and/or
6  * modify it under the terms of the Do What The Fuck You Want To Public
7  * License, Version 2, as published by Sam Hocevar. See the file
8  * COPYING.WTFPL accompanying this distribution or http://www.wtfpl.net/
9  * for more details.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "trovefs.h"
16
17 static char *keys[TROVEFS_MAX_LIST_KEYS];
18
19 typedef struct list_bucket_callback_data
20 {
21         int isTruncated;
22         char nextMarker[1024];
23         int keyCount;
24         int allDetails;
25 } list_bucket_callback_data;
26
27 static S3Status
28 responsePropertiesCallback (const S3ResponseProperties *properties, void *callbackData)
29 {
30         return S3StatusOK;
31 }
32
33 static void
34 responseCompleteCallback (S3Status status, const S3ErrorDetails *error, void *callbackData)
35 {
36         return;
37 }
38
39 static S3Status
40 list_bucket_callback (
41         int isTruncated,
42         const char *nextMarker,
43         int contentsCount,
44         const S3ListBucketContent *contents,
45         int commonPrefixesCount,
46         const char **commonPrefixes,
47         void *callbackData
48 ) {
49         list_bucket_callback_data *data = (list_bucket_callback_data *) callbackData;
50
51         data->isTruncated = isTruncated;
52
53         if ((!nextMarker || !nextMarker[0]) && contentsCount)
54         {
55                 nextMarker = contents[contentsCount - 1].key;
56         }
57         if (nextMarker)
58         {
59                 snprintf (data->nextMarker, sizeof (data->nextMarker), "%s", nextMarker);
60         }
61         else
62         {
63                 data->nextMarker[0] = 0;
64         }
65
66         for (int i = 0; i < contentsCount; i++)
67         {
68                 const S3ListBucketContent *content = &(contents[i]);
69                 keys[i] = malloc (sizeof (content->key));
70                 strcpy (keys[i], content->key);
71         }
72         keys[contentsCount] = malloc (1);
73         keys[contentsCount][0] = '\0';
74         return S3StatusOK;
75 }
76
77 error_t
78 trovefs_s3_get_names (struct trovefs_dir *dir)
79 {
80         error_t err = 0;
81         struct trovefs *fs = dir->fs;
82         S3BucketContext *bucket = fs->s3_ctx;
83
84         S3ListBucketHandler list_bucket_handler =
85         {
86                 { &responsePropertiesCallback, &responseCompleteCallback },
87                 &list_bucket_callback
88         };
89
90         list_bucket_callback_data data;
91
92         S3_list_bucket (
93                 bucket,
94                 dir->rmt_path+1,
95                 "",
96                 "",
97                 TROVEFS_MAX_LIST_KEYS,
98                 0,
99                 &list_bucket_handler,
100                 &data
101         );
102
103         struct trovefs_dir_entry *e = 0;
104         struct trovefs_dir_entry *p;
105
106         for (int i = 0; i < TROVEFS_MAX_LIST_KEYS; i++)
107         {
108                 if (!keys[i] || keys[i][0] == '\0')
109                         break;
110                 p = e;
111                 e = lookup (dir, keys[i], 1);
112
113                 if (! e)
114                         return ENOMEM;
115
116                 e->valid = 1;
117
118                 if (! e->ordered_self_p)
119                 {
120                         e->ordered_self_p = p ? &p->next : &dir->ordered;
121                         if (*e->ordered_self_p)
122                                 (*e->ordered_self_p)->ordered_self_p = &e->ordered_next;
123                         e->ordered_next = *e->ordered_self_p;
124                         *e->ordered_self_p = e;
125                 }
126         }
127
128         return err;
129 }