first commit
This commit is contained in:
commit
637b8c02e6
225
.clang-format
Normal file
225
.clang-format
Normal 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
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.pot
|
||||
*.mo
|
||||
dist
|
67
Makefile
Normal file
67
Makefile
Normal 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
43
README.md
Normal 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
7
examples/Makefile
Normal 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
28
examples/pool/main.c
Normal 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
4
include/all.h
Normal file
@ -0,0 +1,4 @@
|
||||
#include "types.h"
|
||||
#include "pool.h"
|
||||
#include "error.h"
|
||||
#include "libmp.h"
|
25
include/error.h
Normal file
25
include/error.h
Normal 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
5
include/libmp.h
Normal 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
8
include/pool.h
Normal 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
20
include/types.h
Normal 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
17
include/url.h
Normal 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
12
include/util.h
Normal 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);
|
67
locale/tr/LC_MESSAGES/libmp.po
Normal file
67
locale/tr/LC_MESSAGES/libmp.po
Normal 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
36
src/error.c
Normal 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
45
src/libmp.c
Normal 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
89
src/pool.c
Normal 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
203
src/url.c
Normal 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
45
src/util.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user