first commit

This commit is contained in:
ngn 2024-06-20 03:34:32 +03:00
commit 637b8c02e6
19 changed files with 949 additions and 0 deletions

225
.clang-format Normal file
View File

@ -0,0 +1,225 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: DontAlign
AlignArrayOfStructures: Left
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: false
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAfterAttributes: Never
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.pot
*.mo
dist

67
Makefile Normal file
View File

@ -0,0 +1,67 @@
PREFIX = /usr
CC = gcc
PO_SRCS = $(wildcard locale/*/*/*.po)
PO_OUTS = $(patsubst locale/%.po,locale/%.mo,$(PO_SRCS))
PO_DIRS = $(wildcard locale/*/*)
SRCS = $(wildcard src/*.c) $(wildcard src/*/*.c)
OBJS = $(patsubst src/%.c,dist/%.o,$(SRCS))
HDRS = $(wildcard include/*.h)
CFLAGS = -O3 -march=native -fstack-protector-strong -fcf-protection=full -fstack-clash-protection
LIBS = -larchive -linih -lgpgme
VERSION = 24.00
all: dist/libmp.so $(PO_OUTS)
dist/libmp.so: $(OBJS)
mkdir -p dist
$(CC) -shared -o $@ $^ $(LIBS) $(CFLAGS)
dist/%.o: src/%.c
mkdir -p dist
$(CC) -c -Wall -fPIC -o $@ $^ $(LIBS) $(CFLAGS) -DVERSION=\"${VERSION}\"
locale/%.mo: locale/%.po
msgfmt $^ -o $@
locale/%.po: locale/libmp.pot
cp $@ $@.old
if msgmerge $@ $^ -o $@ ; then \
rm $@.old ; \
echo "merge success: $@" ; \
else \
echo "merge failed: $@" ; \
mv $@.old $@ ; \
fi; \
locale/libmp.pot: $(SRCS)
mkdir -p locale
xgettext -k_ -c $^ -o $@
install:
install -m755 dist/libmp.so $(DESTDIR)$(PREFIX)/lib/libmp.so
mkdir -pv $(DESTDIR)/usr/include/libmp
cp $(HDRS) $(DESTDIR)/usr/include/libmp
@for po in $(PO_DIRS) ; do \
echo "installing locale: $$po/libmp.mo" ; \
mkdir -pv $(DESTDIR)/usr/share/$$po ; \
cp $$po/libmp.mo $(DESTDIR)/usr/share/$$po ; \
done
uninstall:
rm $(DESTDIR)$(PREFIX)/lib/libmp.so
rm -r $(DESTDIR)/usr/include/libmp
format:
clang-format -i -style=file src/*.c src/*.c include/*.h examples/*/*.c
examples:
ifeq (,$(wildcard dist/libmp.so))
@echo "!!!! you should first compile libmp !!!!"
exit 1
endif
$(MAKE) -C $@
.PHONY: test install uninstall format examples

43
README.md Normal file
View File

@ -0,0 +1,43 @@
# libmp | MatterLinux package management library
The core library for [`mp`](https://git.matterlinux.xyz/Matter/mp), it has
components for transferring, installing, updating and removing packages.
### Installation
If you are using MatterLinux, this package is most likely already installed,
as it's a core component of the system. If you are not, then you can build
it from the source and install it.
To this you will need the following tools and libraries:
- gcc
- make
- libarchive
- libinih
- gettext
- gpgme
After installing these dependencies, you should download the latest release.
If you are building this library for development purposes, then you may also
build from the latest commit. However latest commit may not always be compilable.
After obtaining the source code, you can compile the library using the make
tool:
```bash
make
```
To install the library you can use the make tool again:
```bash
make install
```
### Tutorial and examples
MatterLinux wiki has a [tutorial for working with this library](https://matterlinux.xyz/wiki/libmp).
There are also some simple examples under the `examples/` directory, you can build these examples
using make:
```bash
make examples
```
To run the examples, specify the library path:
```bash
LD_LIBRARY_PATH=./dist ./dist/example_version
```

7
examples/Makefile Normal file
View File

@ -0,0 +1,7 @@
CC = gcc
all: ../dist/example_pool
../dist/example_pool: pool/*.c ../dist/libmp.so
mkdir -pv ../dist
$(CC) -L../dist $< -lmp -o $@

28
examples/pool/main.c Normal file
View File

@ -0,0 +1,28 @@
#include "../../include/all.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int ret = EXIT_FAILURE;
if(argc != 2){
printf("usage: %s <pool url>\n", argv[0]);
return ret;
}
lm_ctx_t ctx;
lm_ctx_init(&ctx);
ctx.debug = true;
if(!lm_ctx_pool_add(&ctx, "test", argv[1])){
printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error());
goto end;
}
ret = EXIT_SUCCESS;
end:
lm_ctx_free(&ctx);
return ret;
}

4
include/all.h Normal file
View File

@ -0,0 +1,4 @@
#include "types.h"
#include "pool.h"
#include "error.h"
#include "libmp.h"

25
include/error.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
typedef enum lm_error {
LM_ERR_NoError = 0,
LM_ERR_URLBadChar = 1,
LM_ERR_URLBadProtocol = 2,
LM_ERR_URLTooLarge = 3,
LM_ERR_URLHostLarge = 4,
LM_ERR_URLPathLarge = 5,
LM_ERR_URLBadHost = 6,
LM_ERR_URLBadPath = 7,
LM_ERR_URLPortUnknown = 8,
LM_ERR_URLBadPort = 9,
LM_ERR_PoolNoSupport = 10,
LM_ERR_URLEnd = 11,
} lm_error_t;
typedef struct lm_error_desc {
lm_error_t code;
char *desc;
} lm_error_desc_t;
void lm_error_set(lm_error_t code);
lm_error_t lm_error();
char *lm_strerror();

5
include/libmp.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include "types.h"
void lm_ctx_init(lm_ctx_t *ctx);
void lm_ctx_free(lm_ctx_t *ctx);

8
include/pool.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <stdbool.h>
#include "types.h"
bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url);
bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name);
void lm_ctx_pool_clear(lm_ctx_t *ctx);
void lm_ctx_pool_test(lm_ctx_t *ctx);

20
include/types.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include "url.h"
#include <stdbool.h>
typedef struct lm_pool {
struct lm_pool *next;
lm_url_t url;
bool available;
char *name;
} lm_pool_t;
typedef struct lm_ctx {
lm_pool_t *pools; // pool list
char *root; // root path for package installtion
char *temp; // temp path
char *data; // package database path
bool debug; // is debug output enabled?
} lm_ctx_t;

17
include/url.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#define URL_PROTOCOL_MAX 20
#define URL_PATH_MAX 2000
#define URL_HOST_MAX 260
typedef struct lm_url {
uint16_t port;
char protocol[URL_PROTOCOL_MAX+1];
char *host;
char *path;
} lm_url_t;
bool lm_url_parse(lm_url_t *url, char *str);
void lm_url_free(lm_url_t *url);

12
include/util.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <stdbool.h>
#include <libintl.h>
#include "types.h"
#define _(x) gettext(x)
void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...);
bool contains(char *str, char s);
bool eq(char *s1, char *s2);
bool is_letter(char c);
bool is_digit(char c);

View File

@ -0,0 +1,67 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-20 03:33+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/error.c:13
msgid "no error"
msgstr "no error"
#: src/error.c:14
#, fuzzy
msgid "URL contains an invalid character"
msgstr "URL contains an invalid char"
#: src/error.c:15
msgid "URL does not have a valid protocol field"
msgstr "URL does not have a valid protocol field"
#: src/error.c:16
msgid "URL is too large"
msgstr "URL is too large"
#: src/error.c:17
msgid "URL hostname is too large"
msgstr "URL hostname is too large"
#: src/error.c:18
msgid "URL path is too large"
msgstr "URL path is too large"
#: src/error.c:19
msgid "URL does not have a valid hostname"
msgstr "URL does not have a valid hostname"
#: src/error.c:20
msgid "URL does not have a valid path"
msgstr "URL does not have a valid path"
#: src/error.c:21
msgid "URL does not contain a hostname with a valid port number"
msgstr "URL does not contain a hostname with a valid port number"
#: src/error.c:22
msgid "URL protocol port number is unknown"
msgstr "URL protocol port number is unknown"
#: src/error.c:23
msgid "URL is incomplete"
msgstr "URL is incomplete"
#: src/error.c:24
msgid "pool does not support the specified protocol"
msgstr "pool does not support the specified protocol"

36
src/error.c Normal file
View File

@ -0,0 +1,36 @@
#include "../include/error.h"
#include "../include/util.h"
#include <stdlib.h>
lm_error_t error = LM_ERR_NoError;
void lm_error_set(lm_error_t code){
error = code;
}
char *lm_strerror(){
lm_error_desc_t errors[] = {
{.code=LM_ERR_NoError, .desc=_("no error")},
{.code=LM_ERR_URLBadChar, .desc=_("URL contains an invalid character")},
{.code=LM_ERR_URLBadProtocol, .desc=_("URL does not have a valid protocol field")},
{.code=LM_ERR_URLTooLarge, .desc=_("URL is too large")},
{.code=LM_ERR_URLHostLarge, .desc=_("URL hostname is too large")},
{.code=LM_ERR_URLPathLarge, .desc=_("URL path is too large")},
{.code=LM_ERR_URLBadHost, .desc=_("URL does not have a valid hostname")},
{.code=LM_ERR_URLBadPath, .desc=_("URL does not have a valid path")},
{.code=LM_ERR_URLBadPort, .desc=_("URL does not contain a hostname with a valid port number")},
{.code=LM_ERR_URLPortUnknown, .desc=_("URL protocol port number is unknown")},
{.code=LM_ERR_URLEnd, .desc=_("URL is incomplete")},
{.code=LM_ERR_PoolNoSupport, .desc=_("pool does not support the specified protocol")},
};
for(int i = 0; i < sizeof(errors)/sizeof(lm_error_desc_t); i++){
if(errors[i].code == error)
return errors[i].desc;
}
return NULL;
}
lm_error_t lm_error(){
return error;
}

45
src/libmp.c Normal file
View File

@ -0,0 +1,45 @@
// clang-format off
/*
* libmp | MatterLinux package management library
* MatterLinux 2023-2024 (https://matterlinux.xyz)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// clang-format on
#include "../include/libmp.h"
#include "../include/pool.h"
#include <locale.h>
#include <libintl.h>
#include <stdlib.h>
void lm_ctx_init(lm_ctx_t *ctx){
setlocale(LC_ALL, "");
textdomain("libmp");
ctx->pools = NULL;
ctx->data = NULL;
ctx->root = NULL;
ctx->temp = NULL;
ctx->debug = false;
}
void lm_ctx_free(lm_ctx_t *ctx){
lm_ctx_pool_clear(ctx);
return;
}

89
src/pool.c Normal file
View File

@ -0,0 +1,89 @@
#include "../include/error.h"
#include "../include/util.h"
#include "../include/pool.h"
#include <stdio.h>
#include <stdlib.h>
void lm_pool_free(lm_pool_t *pool){
lm_url_free(&pool->url);
free(pool);
}
lm_pool_t *lm_pool_new(char *name, char *url){
lm_pool_t *pool = malloc(sizeof(lm_pool_t));
if(!lm_url_parse(&pool->url, url)){
free(pool);
return NULL;
}
if(!eq(pool->url.protocol, "mptp")){
lm_error_set(LM_ERR_PoolNoSupport);
lm_pool_free(pool);
return NULL;
}
pool->name = name;
return pool;
}
bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url){
lm_pool_t *pool = lm_pool_new(name, url);
if(NULL == pool)
return false;
pdebug(ctx, __func__, "pool name is %s", pool->name);
pdebug(ctx, __func__, "pool URL is %s://%s%s", pool->url.protocol, pool->url.host, pool->url.path);
if(NULL == ctx->pools){
ctx->pools = pool;
return true;
}
lm_pool_t *cur = ctx->pools;
while(NULL != cur) {
if(NULL == cur->next){
cur->next = pool;
return true;
}
cur = cur->next;
}
return false;
}
bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name){
lm_pool_t *cur = ctx->pools, *prev = NULL;
while(NULL != cur) {
if(!eq(cur->name, name)){
cur = cur->next;
continue;
}
if(NULL == prev){
ctx->pools = cur->next;
lm_pool_free(cur);
return true;
}
prev->next = cur->next;
lm_pool_free(cur);
return true;
}
return false;
}
void lm_ctx_pool_clear(lm_ctx_t *ctx){
lm_pool_t *cur = ctx->pools, *prev = NULL;
while(NULL != cur) {
prev = cur;
cur = cur->next;
lm_pool_free(prev);
}
ctx->pools = NULL;
}
void lm_ctx_pool_test(lm_ctx_t *ctx){
return;
}

203
src/url.c Normal file
View File

@ -0,0 +1,203 @@
#include "../include/error.h"
#include "../include/util.h"
#include "../include/url.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char valid_path[] = "-._~:/?#[]@!$&'()*+,;%=";
typedef enum lm_state {
URL_PROTOCOL_0 = 0,
URL_SPLIT_1 = 1,
URL_HOST_2 = 2,
URL_PATH_3 = 3,
} lm_state_t;
uint16_t lm_url_default(char *protocol){
if(eq(protocol, "ftp"))
return 21;
else if(eq(protocol, "ftps"))
return 990;
else if(eq(protocol, "http"))
return 80;
else if(eq(protocol, "https"))
return 443;
else if(eq(protocol, "mptp"))
return 5858;
return 0;
}
bool lm_url_parse(lm_url_t *url, char *str){
// clear out every variable
bzero(url->protocol, sizeof(url->protocol));
url->host = NULL;
url->path = NULL;
url->port = 0;
// stores the string size
size_t strl = 0, index = 0, pos = 0;
// make sure the URL string size is not too large
// extra 4 for "://" and ":"
if((strl = strlen(str)) > URL_PROTOCOL_MAX+URL_PATH_MAX+URL_HOST_MAX+4){
lm_error_set(LM_ERR_URLTooLarge);
return false;
}
lm_state_t state = URL_PROTOCOL_0;
char buffer[strl+1]; // temporary buffer
bool ret = false; // return value
// clear out the temporary buffer
bzero(buffer, strl+1);
while ((buffer[index] = *(str+pos)) != 0) {
switch (state) {
case URL_PROTOCOL_0:
if(index > URL_PROTOCOL_MAX){
lm_error_set(LM_ERR_URLBadProtocol);
goto end;
}
if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != ':'){
lm_error_set(LM_ERR_URLBadChar);
goto end;
}
if(buffer[index] != ':')
break;
if(0 == index){
lm_error_set(LM_ERR_URLBadProtocol);
goto end;
}
buffer[index] = 0;
memcpy(url->protocol, buffer, index+1);
goto next;
case URL_SPLIT_1:
if(index > 1){
lm_error_set(LM_ERR_URLBadProtocol);
goto end;
}
if (buffer[index] != '/'){
lm_error_set(LM_ERR_URLBadChar);
goto end;
}
if(index != 1)
break;
if(buffer[index-1] != '/' || buffer[index] != '/'){
lm_error_set(LM_ERR_URLBadProtocol);
goto end;
}
goto next;
case URL_HOST_2:
if(index > URL_HOST_MAX){
lm_error_set(LM_ERR_URLHostLarge);
goto end;
}
if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != '.' && buffer[index] != ':' && buffer[index] != '/'){
lm_error_set(LM_ERR_URLBadChar);
goto end;
}
if(buffer[index] != '/')
break;
if(index == 0){
lm_error_set(LM_ERR_URLBadHost);
goto end;
}
buffer[index] = 0;
url->host = malloc((index+1)*sizeof(char));
memcpy(url->host, buffer, index+1);
goto next;
case URL_PATH_3:
if(index > URL_PATH_MAX){
lm_error_set(LM_ERR_URLPathLarge);
goto end;
}
if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && !contains(valid_path, buffer[index])){
lm_error_set(LM_ERR_URLBadChar);
goto end;
}
break;
default:
assert(false);
}
index++;
pos++;
continue;
next:
bzero(buffer, strl+1);
state++;
index = 0;
pos++;
}
switch (state) {
case URL_HOST_2:
if(index == 0){
lm_error_set(LM_ERR_URLBadHost);
goto end;
}
if(index > URL_HOST_MAX){
lm_error_set(LM_ERR_URLHostLarge);
goto end;
}
url->host = malloc((index+1)*sizeof(char));
memcpy(url->host, buffer, index+1);
url->path = malloc(2*sizeof(char));
url->path[0] = '/';
url->path[1] = 0;
break;
case URL_PATH_3:
url->path = malloc((index+2)*sizeof(char));
url->path[0] = '/';
memcpy(url->path+1, buffer, index+1);
break;
default:
lm_error_set(LM_ERR_URLEnd);
goto end;
}
ret = true;
end:
if(!ret && NULL != url->host)
free(url->host);
if(!ret && NULL != url->path)
free(url->path);
return ret;
}
void lm_url_free(lm_url_t *url){
if(NULL != url->host)
free(url->host);
if(NULL != url->path)
free(url->path);
}

45
src/util.c Normal file
View File

@ -0,0 +1,45 @@
#include "../include/util.h"
#include "../include/types.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...){
if(!ctx->debug)
return;
va_list args;
va_start(args, fmt);
printf("[DEBUG] %s: ", func);
vprintf(fmt, args);
printf("\n");
va_end(args);
}
bool eq(char *s1, char *s2) {
if (NULL == s1 || NULL == s2)
return false;
if (strlen(s1) != strlen(s2))
return false;
return strcmp(s1, s2) == 0;
}
bool is_letter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
bool is_digit(char c) {
return c >= '0' && c <= '9';
}
bool contains(char *str, char s) {
for (char *c = str; *c != 0; c++)
if (*c == s)
return true;
return false;
}