xref: /linux/fs/smb/client/gen_smb2_mapping (revision 8a5203c630c67d578975ff237413f5e0b5000af8)
1#!/usr/bin/perl -w
2# SPDX-License-Identifier: GPL-2.0-or-later
3#
4# Generate an SMB2 status -> error mapping table,
5# sorted by NT status code (cpu-endian, ascending).
6#
7# Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
8# Written by David Howells (dhowells@redhat.com)
9#
10use strict;
11
12if ($#ARGV != 1) {
13	print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
14	exit(2);
15}
16
17my %statuses = ();
18my @list = ();
19
20#
21# Read the file
22#
23open IN_FILE, "<$ARGV[0]" || die;
24while (<IN_FILE>) {
25	chomp;
26
27	if (m!^#define\s*([A-Za-z0-9_]+)\s+cpu_to_le32[(]([0-9a-fA-Fx]+)[)]\s+//\s+([-A-Z0-9_]+)!) {
28		my $status = $1;
29		my $code = $2;
30		my $ncode = hex($2);
31		my $error = $3;
32		my $s;
33
34		next if ($status =~ /^STATUS_SEVERITY/);
35
36		die "Duplicate status $status"
37			if exists($statuses{$status});
38
39		my %s = (
40			status => $status,
41			code   => $code,
42			ncode  => $ncode,
43			error  => $error
44		);
45		$statuses{$status} = \%s;
46		push @list, \%s;
47	}
48}
49close IN_FILE || die;
50
51
52@list = sort( { $a->{ncode} <=> $b->{ncode} } @list);
53
54open OUT_FILE, ">$ARGV[1]" || die;
55my $list_size = scalar @list;
56my $full_status = "";
57for (my $i = 0; $i < $list_size; $i++) {
58	my $entry = $list[$i];
59	my $status = $entry->{status};
60	my $code   = $entry->{code};
61	my $ncode  = $entry->{ncode};
62	my $error  = $entry->{error};
63
64	next if ($ncode == 0);
65
66	$full_status .= $status;
67	# There may be synonyms
68	if ($i < $list_size - 1) {
69		my $next_entry = $list[$i + 1];
70		my $next_ncode = $next_entry->{ncode};
71		if ($next_ncode == $ncode) {
72			$full_status .= " or ";
73			next;
74		}
75	}
76
77	my $pad = " ";
78	if (length($full_status) < 40) {
79		my $n = 40 - length($full_status);
80		$pad = "\t" x ((($n-1) / 8) + 1);
81	}
82	print(OUT_FILE "{ $code, $error, \"$full_status\" },\n");
83
84	$full_status = "";
85}
86close OUT_FILE || die;
87