summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/taskmanager/tasks/ListArchive.java
blob: b45c0ed493b5f97bc9f5bad1fe9c31beecb3bd21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package org.openslx.taskmanager.tasks;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.io.FilenameUtils;
import org.openslx.satserver.util.Archive;
import org.openslx.satserver.util.Util;
import org.openslx.taskmanager.api.AbstractTask;

import com.google.gson.annotations.Expose;

public class ListArchive extends AbstractTask
{

	@Expose
	private String file;

	/*
	 * Own vars/constants not being deserialized
	 */

	protected static final String[] ALLOWED_DIRS = { "/tmp/", "/opt/openslx/" };

	private Output status = new Output();

	/*
	 * Code
	 */

	@Override
	protected boolean execute()
	{
		ArchiveInputStream archive;
		try {
			archive = Archive.getArchiveInputStream( this.file );
		} catch ( FileNotFoundException e1 ) {
			status.error = e1.getMessage();
			status.errorCode = Output.ErrorCode.NOT_FOUND;
			return false;
		} catch ( IllegalArgumentException e1 ) {
			status.error = e1.getMessage();
			status.errorCode = Output.ErrorCode.UNKNOWN_ERROR;
			return false;
		} catch ( ArchiveException e1 ) {
			status.error = e1.getMessage();
			status.errorCode = Output.ErrorCode.UNKNOWN_FORMAT;
			return false;
		}

		List<Output.Entry> entries = new ArrayList<>();

		ArchiveEntry archiveEntry;
		try {
			// Iterate over every entry
			while ( ( archiveEntry = archive.getNextEntry() ) != null ) {
				if ( !archive.canReadEntryData( archiveEntry ) )
					continue;
				Output.Entry entry = new Output.Entry();
				entry.name = archiveEntry.getName();
				entry.isdir = archiveEntry.isDirectory();
				if ( archiveEntry instanceof TarArchiveEntry ) {
					entry.user = ( (TarArchiveEntry)archiveEntry ).getUserName();
					entry.userId = ( (TarArchiveEntry)archiveEntry ).getLongUserId();
					entry.group = ( (TarArchiveEntry)archiveEntry ).getGroupName();
					entry.groupId = ( (TarArchiveEntry)archiveEntry ).getLongGroupId();
					if ( ( (TarArchiveEntry)archiveEntry ).isSymbolicLink() ) {
						entry.linkTarget = ( (TarArchiveEntry)archiveEntry ).getLinkName();
					}
				}
				entry.size = archiveEntry.getSize();
				entries.add( entry );
			}
		} catch ( IOException e ) {
			return false;
		}
		status.entries = entries;
		return true;
	}

	@Override
	protected boolean initTask()
	{
		this.setStatusObject( this.status );
		if ( this.file == null || this.file.length() == 0 || this.file.charAt( 0 ) != '/' ) {
			status.error = "Need absolute path.";
			status.errorCode = Output.ErrorCode.INVALID_DIRECTORY;
			return false;
		}
		this.file = FilenameUtils.normalize( this.file );
		if ( this.file == null || !Util.startsWith( this.file, ALLOWED_DIRS ) ) {
			status.error = "File not in allowed directory";
			status.errorCode = Output.ErrorCode.INVALID_DIRECTORY;
			return false;
		}
		return true;
	}

	@SuppressWarnings( "unused" )
	private static class Output
	{
		protected String error = null;

		protected enum ErrorCode
		{
			NOT_FOUND, UNKNOWN_FORMAT, UNKNOWN_ERROR, INVALID_DIRECTORY
		};

		protected ErrorCode errorCode = null;
		protected List<Entry> entries = null;

		public static class Entry
		{
			protected String name = null;
			protected String linkTarget = null;
			protected boolean isdir = false;
			protected String user;
			protected long userId = -1;
			protected long groupId = -1;
			protected String group;
			protected long size = -1;
		}
	}

}